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
Related
I'm trying to search value inside Corda unconsumed states on a collection Field.
I'm able to search on String field using -
Field uniqueAttributeName = MySchema.PersistentIOU.class.getDeclaredField("fieldname");
CriteriaExpression uniqueAttributeEXpression = Builder.equal(uniqueAttributeName, "valueToSearch");
QueryCriteria customCriteria = new QueryCriteria.VaultCustomQueryCriteria(uniqueAttributeEXpression);
result = rpcOps.vaultQueryByCriteria(customCriteria, MyState.class).getStates();
Above worked fine when "fieldname" is String but I have another field which is List and I'm not sure how to search inside List for a specific value.
Please assist.
After a quick chat with #Roger3cev, we think the best way is to amend your ORM wrapper such that you have a parent - child relationship between the state and the list of fields you want to have in that list. Once you do this, you can use the JDBC connection available to you to query against the child state and then use the relationship to the parent to get the Corda state.
I'm using neo4j-jdbc 2.3.2 as my neo4j client for java. When I executed following cypher query
match(p:Person) where p.id_number='761201948V' return p.id; it will return P2547228 as node id. I feel like id is same as other properties of the node as I can use it inside where clauses. But here I'm expecting an integer which can use inside this query START p=node('node.id') return p; Is this id is an internal thing to neo4j db? and is there a way to retrieve this id?
From the following two cyphers what is most efficient one?(if both referring same node)
START p=node('2547223') return p;
match(p:Person) where p.id='P2547228' return p;
You have to use the ID(x) function for this. Note, that ID(x) and x.id are a complete different thing. The former returns the internal node/relationship id managed by Neo4j itself. The latter gives the id property which is managed by the user and not by the database itself.
Also note, that a node/relationship ID is always numeric.
Using START is pretty much old school and shouldn't be used any more (except for accessing manual indexes):
start p=node(2547228) return p
This one is a equivalent statement. It is highly efficient since it just needs to do a simple seek operation on the node store:
match(p:Person) where id(p)=2547228 return p;
Looking for a property requires either a node label scan or a schema index lookup:
match(p:Person) where p.id=2547228 return p;
Just check out the query plans on your own by prefixing the statement with PROFILE.
Trying to retrieve nodes in SDN, imported using the Neo4j CSV Batch Importer, gives the java.lang.IllegalStateException:
java.lang.IllegalStateException: No primary SDN label exists .. (i.e one with starting with _)
This is after having added a new label through a cypher query:
match (n:Movie) set n:_Movie;
Inspecting nodes created through SDN shows they have the same labels. The result when running
match (n) where id(n)={nodeId} return labels(n) as labels;
as found in LabelBasedStrategyCypher.java is the same for both:
["Movie","_Movie"]
Saving and retrieving nodes thorugh SDN works without any issues. I must be missing something as I got the impression that setting the appropiate labels should be enough.
I'm running SDN 3.0.2.RELEASE and neo4j 2.0.3 on arch linux x64 with Oracle Java 1.8.0_05
Edit: My CSV file looks like this. The appId is only used to assure the node is the same that we have stored earlier, as the internal nodeId is Garbage collected and new nodes could get old nodeIds after the old ones are deleted. The nodeId is used for actual lookups and for connecting relationships and so on.
appId:int l:label title:string:movies year:int
1 Movie Dinosaur Planet 2003
2 Movie Isle of Man TT 2004 Review 2004
Edit2:
I have made more tests, checking the source of LabelBasedNodeTypeRepresentationStrategy to see what is going wrong. Running the readAliasFrom() method that the Exception is thrown from does not return any errors:
String query = "start n=node({id}) return n";
Node node = null;
for(Node n : neo4jTemplate.query(query,params).to(Node.class)){
node = n;
}
// when running the readAliasFrom method manually the label is returned correctly
LabelBasedNodeTypeRepresentationStrategy strategy = new
LabelBasedNodeTypeRepresentationStrategy(neo4jTemplate.getGraphDatabase());
System.out.println("strategy returns: " +(String)strategy.readAliasFrom(node));
// trying to convert the node to a movie object, however throws the Illegal State Exception
Movie movie = null;
movie = neo4jTemplate.convert(node,Movie.class);
So, the _Movie label exists, running the readAliasFrom() method manually doesn't throw Exceptions but trying to convert the node into a Movie does. Nodes created from SDN do not have these issues, even if they look identical to me.
Here I have created a manual/legacy index and added some nodes with certain properties into it.
IndexManager indexy = graphdb.index();
Index<Node>indexery = indexy.forNodes("Main_Twitter_Index");
indexery.add(one,"Name",one.getProperty("Name"));
indexery.add(one,"Email",one.getProperty("Email"));
indexery.add(four,"Name",four.getProperty("Name"));
indexery.add(four,"Email",four.getProperty("Email"));
Now, to query the nodes of that index neo4j suggests query, which uses a key-value pair binding. My question is can I query the same nodes added into the manual index using a simple cypher query like,
START n=node:Main_Twitter_Index(Name = 'Akina')
RETURN n
Which version of Neo4j are you using? The method you describe is the typical index search for anything before 2.0, before they added schema indexing. Your query should work, even in 2.0. Are you having problems running it?
I am new to hibernate and still learning the basics. I'd appreciate if someone can point me in the right direction.
I have a class:
Destination
id
name
longitude
latitude
I can read destinations based on id with something like this:
List result = session.createQuery("from Destination as d where d.id=2").list();
However, I want to read destinations from database using name. I can perhaps write something like this as a query:
String name; // name set somewhere else, say a function argument
List result = session.createQuery("from Destination as d where d.name LIKE %"+name).list();
I believe this will yield all destinations with names similar to (variable) name.
Is there something inbuilt in hibernate for such use cases or is there a better way to handle this ?
EDIT:
One thing that follows from my thought process is: name column on destination db table will have an index setup. Can I map this index in some way to the Destination class using hibernate ?
You could build your query by concatenating strings. A more elegant solution would be to use the Hibernate Criteria API.
You query would then look something like:
List result = session.createCriteria(Destination.class)
.add(Restrictions.like("name", "%" + name)
.list();