Reputation: 3826
Hello I am trying to match neo4j relationships using 'WHERE AND'
My example relationiship is: 'User Visits Country'
I create it as so...
MATCH (c:Country{Name:Country}) MERGE (u:User{Email:Email,UserID: UserID}) MERGE (u)-[r:Visits]->(c)
//Countries are previously created and Users may or may not exist
Then I query (This Works):
MATCH (u:User)-[r:Visits]->(c:Country) where c.Name='France' or c.Name='Spain' return u
Result: Shows me all users who have visited Spain OR France, even if they have only visited one of two countries.
BUT What Im trying to do is the same exact query, but with 'AND' instead of 'OR'. In which I can get users that have visited both 'France' and 'Spain'.
MATCH (u:User)-[r:Visits]->(c:Country) where c.Name='France' AND c.Name='Spain' return u
Result: 0 nodes and relationship found..
What can I do?
Upvotes: 3
Views: 15532
Reputation: 11216
In your query you are matching a single country node and saying the name of that node has to be France
and has to be Spain
.
What you want is to find all of the users that have vistied both France and Spain. There are a couple of ways you can go...
//match both countries against the same user and identify them separtely
//making two matches in a single query
MATCH (u:User)-[:VISITS]->(c1:Country), (u)-[:VISITS]->(c2:Country)
WHERE c1.name = "France"
AND c2.name = "Spain"
RETURN u.name
//match all users that have been to either and only return the one that have been to both
MATCH (u:User)-[r:VISITS]->(c:Country)
WHERE (c.name IN [ "France", "Spain"])
WITH u, count(*) AS num
WHERE num = 2
RETURN u.name, num
It think number one is better as it is more precise and probably more efficient.
Upvotes: 9
Reputation: 2996
What's wrong in your query
MATCH (u:User)-[r:Visits]->(c:Country)
where c.Name='France'
AND c.Name='Spain'
return u
This will always return no rows because you are trying to check two values for the same node's property.
Solution
MATCH (c1:Country)<-[r:Visits]-(u:user)-[r1:Visits]->(c2:Country)
WHERE c1.name = 'France' AND c2.name = 'Spain'
RETURN u.name;
This will return what you need.
Here is one short and useful reference doc of Neo4j: http://neo4j.com/docs/2.1.2/cypher-refcard/
Upvotes: 2
Reputation: 67044
If you only care about 2 countries. this query would also work, in addition to the options provided by @DaveBennett.
MATCH (c1)<-[:VISITS]-(u)-[:VISITS]->(c2)
WHERE c1.name = "France" AND c2.name = "Spain"
RETURN u.name;
Upvotes: 3