Given a Neo4J Node with an array property, how do I create a Cypher query to return only the node(s) that match an array literal?
Using the console I created a node with the array property called "list":
neo4j-sh (0)$ create n = {list: [1,2,3]};
==> +-------------------+
==> | No data returned. |
==> +-------------------+
==> Nodes created: 1
==> Properties set: 1
==> 83 ms
neo4j-sh (0)$ start n=node(1) return n;
==> +-----------------------+
==> | n |
==> +-----------------------+
==> | Node[1]{list:[1,2,3]} |
==> +-----------------------+
==> 1 row
==> 1 ms
However, my query does not return the Node that was just created given a WHERE clause that matches an array literal:
neo4j-sh (0)$ start n=node(1) where n.list=[1,2,3] return n;
==> +---+
==> | n |
==> +---+
==> +---+
==> 0 row
==> 0 ms
It's entirely possible I'm mis-using Cypher. Any tips on doing exact array property matching in Cypher would be helpful.
The console is always running the latest SNAPSHOT builds of Neoj4. the version refers to the Cypher Syntax parswer, we will point that out more clearly :)
Now, there has been some fixing around the Array handling in Cypher, see https://github.com/neo4j/community/pull/815 and https://github.com/neo4j/community/issues/818 which problably are the ones that make the console work. This has been merged in after 1.8.M07, so in order to get it work locally, please download one of the latest 1.8.-SNAPSHOT, build it from GITHUB or wait for 1.8.M08 which is due very soon.
/peter
Which version of Neo4j are you using?
Your same code works for me in 1.8M07.
http://console.neo4j.org/?id=p9cy6l
Update:
I get the same result (no results) in a local install via the web client. Maybe it's a web client issue?
Related
I am trying to find the shortest path between two nodes but I need to exclude some nodes from the path. The cypher that I am trying is
START a=node(1), b=node(2), c=node(3,4)
MATCH p=a-[rel:RELATIONSHIP*]-b
WHERE NOT (c in nodes(p))
RETURN p
ORDER BY length(p) LIMIT 1
But this is giving me a path which includes one of the nodes in c.
Is there a way to do a traversal excluding some nodes?
Thanks
The MATCH ... WHERE part should be fine, but your START clause may not do what you expect. Do the following and consider the result
START a=node(1), b=node(2), c=node(3,4)
RETURN ID(a), ID(b), ID(c)
You get back
==> +-----------------------+
==> | ID(a) | ID(b) | ID(c) |
==> +-----------------------+
==> | 1 | 2 | 3 |
==> | 1 | 2 | 4 |
==> +-----------------------+
That means the rest of the query is executed twice, once excluding (3) from the path and once excluding (4). But that also means of course that it is run once not excluding each of them, which means you can indeed get results with those nodes present on the path.
If you want to exclude both of those nodes from the path, try collecting them and filtering with NONE or NOT ANY or similar. I think something like this should do it (can't test at the moment).
START a=node(1), b=node(2), c=node(3,4)
WITH a, b, collect (c) as cc
MATCH p=a-[rel:RELATIONSHIP*]-b
WHERE NONE (n IN nodes(p) WHERE n IN cc)
RETURN p
ORDER BY length(p) LIMIT 1
This is the number of nodes before I create the new one:
neo4j-sh (0)$ match n return n;
==> +------------------------------------------------------------------------+
==> | n |
==> +------------------------------------------------------------------------+
==> | Node[0]{} |
==> | Node[1]{address:"rioeduardo92#gmail.com",comment:"home",person_id:"1"} |
==> | Node[2]{address:"rioeduardo92#yahoo.com",comment:"work",person_id:"1"} |
==> | Node[3]{person_id:"1",name:"Rio"} |
==> +------------------------------------------------------------------------+
after I created the new one, the node that I just created is started from node number 300:
neo4j-sh (0)$ create (n:lolo{color:'blue'}) return n;
==> +-------------------------+
==> | n |
==> +-------------------------+
==> | Node[300]{color:"blue"} |
==> +-------------------------+
Thank you
It's not the number of nodes increasing but the internal node id. If you created a lot of nodes and deleted them for example, then your new node might have taken up the next highest id (300) because the old id's haven't been recycled yet.
Which is why you should never count on the internal node ID to serve as an identifier/key on your nodes.
start n=node(*) return count(n)
should give you the true number of nodes in your graph
The structure of my nodes are like this:
==> | Node[613]{name:"The Bigos",fs_id:"51a8e1a12fc6e7ef6d121077"}
==> | Node[614]{name:"Maceraperest",fs_id:"51bafb3d498ed54bd4c7fa8c"}
==> | Node[616]{name:"Viking",fs_id:"51bafe1de4b090ea9dceb20e"}
==> | Node[618]{name:"Metro Gross Market",fs_id:"51bb426c498e47af428ca013"}
When I try to create these nodes again, a php script I wrote checks on fs_id to find that if the node already exists or not. If it exists, it returns me the node and does not create a new one.
Now the problem is that even though it does not create new nodes, the console shows me that it did.
==> | Node[613]{name:"The Bigos",fs_id:"51a8e1a12fc6e7ef6d121077"}
==> | Node[613]{name:"The Bigos",fs_id:"51a8e1a12fc6e7ef6d121077"}
==> | Node[613]{name:"The Bigos",fs_id:"51a8e1a12fc6e7ef6d121077"}
==> | Node[614]{name:"Maceraperest",fs_id:"51bafb3d498ed54bd4c7fa8c"}
==> | Node[614]{name:"Maceraperest",fs_id:"51bafb3d498ed54bd4c7fa8c"}
==> | Node[614]{name:"Maceraperest",fs_id:"51bafb3d498ed54bd4c7fa8c"}
==> | Node[616]{name:"Viking",fs_id:"51bafe1de4b090ea9dceb20e"}
==> | Node[616]{name:"Viking",fs_id:"51bafe1de4b090ea9dceb20e"}
==> | Node[616]{name:"Viking",fs_id:"51bafe1de4b090ea9dceb20e"}
==> | Node[618]{name:"Metro Gross Market",fs_id:"51bb426c498e47af428ca013"}
==> | Node[618]{name:"Metro Gross Market",fs_id:"51bb426c498e47af428ca013"}
==> | Node[618]{name:"Metro Gross Market",fs_id:"51bb426c498e47af428ca013"}
Look at the node ids, they are same! And if I explore the node 618 for example in the data browser, it returns me a single node. Also the query
start n=node(618) return n;
also returns single row. But the query below returns multiple rows of same node id and the row count is increasing when I test the above nodes for existence.
start n=node(331) match n-[:BEEN]->(venues) return venues order by id(venues);
It might be nothing but I'm curious that if somehow Neo4j is eating extra memory for doing this or it is just something like caching system.
You probably just have multiple BEEN relationships, then each of those relationships yields another result row.
If you just have one row per venue do this:
start n=node(331)
match n-[:BEEN]->(venues)
return distinct venues;
to see the different relationships, use:
start n=node(331)
match n-[rel:BEEN]->(venues)
return venues,collect(rel);
I am trying out neo4j and I downloaded and successfully configured the example dataset cineasts_39_movies_446_actors.zip from here
I can query node 1 fine:
neo4j-sh (0)$ START n=node(1) RETURN n
==> +------------------------------------------------------------------------------------------------------------------------------------------------------------+
==> | n |
==> +------------------------------------------------------------------------------------------------------------------------------------------------------------+
==> | Node[1]{login:"micha",roles:["ROLE_ADMIN","ROLE_USER"],name:"Micha",password:"339f455efd4af00b3e62385f3b7ef694",__type__:"org.neo4j.cineasts.domain.User"} |
==> +------------------------------------------------------------------------------------------------------------------------------------------------------------+
How can I query nodes with name Micha? Thanks
How about:
start n=node:User("login:micha") return n;
The syntax for index lookups is like so:
<node/relationship>:<index name>(<lucene query/shorthand single field lookup>)
The shorthand looks like this, and makes it easier to parameterize:
start n=node:User(login="micha") return n;
And parameterized in JSON like so:
{query:"start n=node:User(login={username}) return n;", params:{username:"micha"}}
I'm discovering a new graph data model in Neo4j and I was wondering how to list all the possible node properties but not their value if possible.
For the relations, I found this very handy generic cypher query :
start n=node(*)
match n-[r]-m
return distinct type(r)
which return a useful list of properties you can start to use to query more specifically the graph:
==> +------------+
==> | type(r) |
==> +------------+
==> | "RATED" |
==> | "FRIEND" |
==> | "DIRECTED" |
==> | "ACTS_IN" |
==> +------------+
==> 4 rows
==> 0 ms
==>
Is there any function/expression that allows to do this but for the node properties ?
Thanks
type() does not return relationship properties, but the relationship type.
Both nodes and relationships can have properties, but only relationships can have a type.
To list all the properties of nodes in graph DB, you can try using following cypher:
match (n)
WITH distinct keys(n) as properties
UNWIND properties as property
return distinct property
Thanks,
Vishal