How to get Vertex from provided attribute / key in Titan - java

I am following code on Titan Documentation GraphOfTheGodsFactory source code I want to retrieve a vertex from the graph, given some specified value / key / attribute.
I searched on documentation (I am using Titan 0.5.2), and tried using different functions, they provide null when executed.
Things I tried,
`TitanManagement mgmt = graph.getManagementSystem();
final PropertyKey userid = mgmt.makePropertyKey("userid").dataType(Integer.class).make();
TitanGraphIndex namei = mgmt.buildIndex("userid",Vertex.class).addKey(userid).unique().buildCompositeIndex();
TitanTransaction tx = graph.newTransaction();
Vertex ver1 = tx.addVertexWithLabel("user");
ver1.setProperty("userid", "2");
ver1.setProperty("username", "abc");
Vertex found = graph.getVertex("2");`
found returns null.
Please help!

You can't find a Vertex this way:
Vertex found = graph.getVertex("2");
That method looks a vertex up by id, but there is no vertex in the graph with the id of "2" that is a String. Now, because you have ver1, you do know the actual id of that Vertex so you can do:
Vertex found = graph.getVertex(ver1.getId());
Typically, you don't always have that identifier so you want to look things up by your domain data and the indices that you've created. In that case you do:
Vertex found = graph.getVertices("userid","2").next();
That will do an index lookup on your userid property. Since that actually returns an Iterator you have to next() off the result. Obviously, in this case, this only returns one result so no worries about anything else in the Iterator but you should probably account for that in some way in some real code.

Related

How do I update many attributes in DynamoDB

I've seen a lot of examples of using UpdateExpression to update attributes using the updateItem method. However, I still don't understand how to update multiple attributes in DynamoDB at the same time dynamically.
I am trying to update AND rename multiple attributes in the same updateItem call.
I understand that this requires a REMOVE of the old name and a SET of the new name. I have these names in hashedId's of objects, but won't have them until runtime. So my question is how do I use UpdateExpression with variables and not a hard-coded String?
All the examples I have seen use hard-coded UpdateExpressions.
can't update item in DynamoDB
Dynamo DB : UpdateItemSpec : Multiple Update Expression - Not Working
DynamoDB update Item multi action
How to rename DynamoDB column/key
I am working in Java.
It seems very odd to me that I haven't been able to find an example of this... which leads me to believe I am doing something wrong.
Thanks for the help!
You have to build the update expression string dynamically based on the attribute names and values that you receive at runtime. I do exactly this. I'm not working in Java, but here is some pseudo code (with a Ruby bias) example for you that dynamically builds the update expression string, the expression attribute names hash, and the expression attribute values hash. You can then plug in these 3 things into the update_item method:
update_exp_set = [] //array of remove expression snippets
update_exp_remove = [] //array of update expression snippets
exp_attribute_names = {} //hash of attribute names
exp_attribute_values = {} //hash of attribute values
// Iterate through all your fields and add things as needed to your arrays and hashes.
// Two examples are below for a field with the name <fieldName> and value <fieldValue>.
// You'll need to convert this to Java and update it to make sense with the AWS Java SDK.
// For a given field that needs to be updated:
update_exp_set << "#<fieldName> = :fieldValue" //add to array of set expression snippets
exp_attribute_names["#<fieldName>"] = "<fieldName>" //add to hash of attribute names
exp_attribute_values[":<fieldValue>"] = "<fieldValue>" //add to hash of attribute values
// For a given field that needs to be removed:
update_exp_remove << "#<fieldName>"
exp_attribute_names["#<fieldName>"] = "<fieldName>" //add to hash of attribute names
// Use your snippets to create your full update expression:
update_exp_set_clause = ""
update_exp_remove_clause = ""
if update_exp_set.length != 0 //check if you have something to set
update_exp_set_clause = "SET " + update_exp_set.join(',')
end
if update_exp_remove.length != 0 //check if you have something to remove
update_exp_remove_clause = "REMOVE" + update_exp_remove.join(',')
end
final_update_exp = update_exp_set_clause + " " + update_exp_remove_clause
Does this help?

Can we convert Result in ResultSet to Vertex by using gremlin - java client?

I am using a Github example to generate a graph (https://github.com/Azure-Samples/azure-cosmos-db-graph-java-getting-started). And now I want to query it and hold a vertex instance in my hand to traverse further depending on further inputs from the user in a knowledge graph.
Submitting this gremlin query: g.V().hasLabel('schedule').inE().outV().hasLabel('url').as('a').dedup()
.where(and(out().hasLabel('schedule').has('name','3'),out()
.hasLabel('states').has('name', 'federal'))).select('a')
// Submitting remote query to the server.
ResultSet results = client.submit(query);
CompletableFuture<List<Result>> completableFutureResults = results.all();
List<Result> resultList = completableFutureResults.get();
for (Result result : resultList) {
System.out.println("My vertex--"+result.getVertex());
System.out.println("\nQuery result:");
System.out.println("resultssssss-"+result.toString());
}
How can I do that as right now I am getting a class cast exception as mentioned below:
java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to org.apache.tinkerpop.gremlin.structure.Vertex
at org.apache.tinkerpop.gremlin.driver.Result.getVertex(Result.java:131)
at GetStarted.Dynamic.main(Dynamic.java:155)
The select('a') seems redundant to me - I think that can be removed. It is selecting an output that is already the current output of where() which is already that vertex at "a" which means your traversal should be:
g.V().hasLabel('schedule').
in().hasLabel('url').
dedup().
where(and(out().hasLabel('schedule').has('name','3'),
out().hasLabel('states').has('name', 'federal')))
I guess a further optimization would be to do the out() before the and() so you only traverse those edges once:
g.V().hasLabel('schedule').
in().hasLabel('url').
dedup().
where(out().and(has('schedule','name','3'),
has('states', 'name', 'federal')))
Now...that returns a Vertex, however, what you had should have also returned a Vertex. At least according to TinkerPop specifications, when doing a select() on a single label you should get back a single object. However, if you do multiple labels then you would get a Map. You can see this demonstrated with TinkerGraph here:
gremlin> g.V().hasLabel('person').as('a').out().as('b').select('a')
==>v[1]
==>v[1]
==>v[1]
==>v[4]
==>v[4]
==>v[6]
gremlin> g.V().hasLabel('person').as('a').out().as('b').select('a','b')
==>[a:v[1],b:v[3]]
==>[a:v[1],b:v[2]]
==>[a:v[1],b:v[4]]
==>[a:v[4],b:v[5]]
==>[a:v[4],b:v[3]]
==>[a:v[6],b:v[3]]
It makes me wonder if CosmosDB has that little nuance covered properly - if not, then that's technically a "bug".

Why is this Java query failing? returning 0 when there are results

Hi can anyone tell me why this java query is failing?
Query q = entityManager.createNativeQuery("SELECT m.* FROM MdmAudit m WHERE m.correlationID = :correlationId AND m.verb = :verb", MdmAuditDAO.class);
//Query q = entityManager.createNamedQuery("MdmAuditDAO.GetData");
q.setParameter("correlationId", resp.getHeader().getCorrelationID());
q.setParameter("verb", resp.getHeader().getVerb());
long result = (long) q.getFirstResult();
The namedQuery:
#NamedQuery( name="MdmAuditDAO.GetData", query="SELECT m FROM MdmAuditDAO m WHERE m.correlationId = :correlationId AND m.verb = :verb")
public class MdmAuditDAO implements Serializable {
I have getters and setter in my MdmAuditDAO class, and I have checked the naming of the variables, and they are identical as in the NamedQuery, so the problem does not lie there.
My problem is that I have three entries in my database, I should at least get one answer back but I get 0 in my result.
MdmAuditDAO is defined in my persistence.xml and in my ehcache.xml. So why is it that the result I get returned is 0? I have also tried to get an object returned or a list of objects, and it is the same result, nothing gets returned, but when I run my query in my mssql database I get results see picture below. It has nothing to do with the m.* I aslo get results when I use that in my SELECT statement.
EDIT 1: This is what I get from my hibernate log, and I do not know how to read this?
Hibernate:
select
mdmauditda0_.id as id1_7_,
mdmauditda0_.correlationID as correlat2_7_,
mdmauditda0_.messageID as messageI3_7_,
mdmauditda0_.meter_no as meter_no4_7_,
mdmauditda0_.noun as noun5_7_,
mdmauditda0_.payload as payload6_7_,
mdmauditda0_.source as source7_7_,
mdmauditda0_.subtype as subtype8_7_,
mdmauditda0_.time as time9_7_,
mdmauditda0_.verb as verb10_7_
from
MdmAudit mdmauditda0_
where
mdmauditda0_.correlationID=?
Anything I have to set, to get more information? I am using the following jars
And my java version is 1.7.0_79.
I found the solution http://www.objectdb.com/api/java/jpa/Query/getFirstResult returns the position of the first element, but I was a bit confused by the phrase
Returns 0 if setFirstResult was not applied to the query object.
Could not get my head around it to make any sense of it.
My solution now is that I just return a list of objects
Query q = entityManager.createNativeQuery("SELECT m.* FROM MdmAudit m WHERE m.correlationId = :correlationId AND verb = :verb", MdmAuditDAO.class);
//Query q = entityManager.createNamedQuery("MdmAuditDAO.GetData");
q.setParameter("correlationId", resp.getHeader().getCorrelationID());
q.setParameter("verb", resp.getHeader().getVerb());
List<MdmAuditDAO> mdmAuditList = q.getResultList();
And then it works fine and I get results. So instead of the the result == 0 check I am doing later in my code I just do a NULL and isEmpty() check instead().
Side note: I have not tried to delete entries and then see what the result would be then in the q.getFirstResult() call but that would be a possibility and see what i get returned and then check on that value, properbly null?

OrientDB vertex relationships efficient search

I am new to OrientDB and have these questions:
- Is there any more efficient way to get the relationships for a given entity than this method:
Iterable<Edge> vet1 = first_vertex.getEdges(Direction.valueOf("BOTH"));
for (Edge edge : vet1)
System.out.println(edge);
Should I parse the result edge e.g., [#9:526597-is_a->#9:8151] by myself to get for example this result: A is_a -> B ?
I should directly get the vertex names (also relationship type and direction) instead of getting only ids and then search for vertex names.
I have a solution but maybe there is faster than it is:
System.out.println(edge.getVertex(Direction.valueOf("OUT")).getProperty("name").toString() + edge.getLabel() + edge.getVertex(Direction.valueOf("IN")).getProperty("name").toString());
Thanks a lot
You can use
Iterable<Vertex> vet1=first_vertex.getVertices(Direction.BOTH, null);
for (Vertex v : vet1)
System.out.println(v);

Neo4j-ogm query path

In my Java code I have a query to match the shortest path from root to a leaf in my tree.
Strinq query = "Match path = (p:Root)-[*1..100]-(m:Leaf) "
+ "WITH p,m,path ORDER BY length(path) LIMIT 1 RETURN path";
However, when I try to query this as follows
SessionFactory sessionFactory = new SessionFactory("incyan.Data.Neo4j.Models");
Session session = sessionFactory.openSession("http://localhost:7474");
Object o = session(query, new HashMap<String,Object>());
o contains an ArrayList of LinkedHashMaps instead of mapped objects.
I cannot even determine the labels of the path elements and the start and end nodes of the relations.
What am I doing wrong?
The current neo4j-ogm release does not map query results to domain entities. Returning a path will only give you the properties of nodes and relationships in that path (in order, so you can infer the relationship start/end). ID's aren't returned by the Neo4j REST api currently used by the OGM for this particular operation and that's why they are missing. You may instead have to extract the ID's and return them as part of your query.
Mapping individual query result columns to entities will be available in a Neo4j-OGM 2.0 release.
I'm not sure about the Java bit, but if you use the shortestPath function (keyword?) your query should be more efficient:
MATCH path=shortestPath((p:Root)-[*1..100]-(m:Leaf))
RETURN path
Also, I don't know what your data model is like, but I would expect the labels on the nodes of your tree (I'm assuming it's a tree) to all be the same. You can tell if a node is a root or a leaf using Cypher:
MATCH path=shortestPath((root:Element)-[*1..100]-(leaf:Element))
WHERE NOT((root)-[:HAS_PARENT]->()) AND NOT(()-[:HAS_PARENT]->(leaf))
RETURN path

Categories

Resources