I’m really new to NEO4J and currently testing some simple Cypher queries.
I want to model users and their hobbies, where one user can have multiple hobbies.
Users and their hobby are created as nodes with the respective labels :User and :Hobby.
The query suggestion from @cobra seems not work in this case
MATCH (u:User)-[:HAS_HOBBY]->(h:Hobby)
WITH u, collect(DISTINCT h.name) AS hobbies
WHERE all(x IN hobbies WHERE x IN ["Sport", "Music"])
RETURN u
Result: Joe
As i can understand the query the result seems to be logical. The hobby Sport from user Joe
satisfies
x IN hobbies WHERE x IN ["Sport", "Music"]
and because the user Joe has only one hobby the all predicate is also fulfilled.
The query suggestion from @ameyasoft works and only the user Max is returned.
But the disadvantage is that you have to use a variable name for every hobby
in the query.
I am particularly thinking about how the query can be easily and dynamically constructed when the hobby filter comes from some sort of user interface. The user can select several hobbies via a checkbox.
I would like to use the query syntax from @cobra to combine multiple filters at once.
For example, to further narrow down the user result set by character details.
MATCH (u:User)-[:HAS_HOBBY]->(h:Hobby)
WITH u, collect(DISTINCT h.name) AS hobbies
WHERE all(x IN ["Sport", "Music"] WHERE x IN hobbies)
WITH u
MATCH (u)-[:HAS_CHARACTER]->(c:CharacterDetail)
WITH u, collect(DISTINCT c.name) AS cdetails
WHERE all(x IN ["Calm", "Spontaneous"] WHERE x IN cdetails)
WITH U
*** NEXT FILTER ***
WITH U
*** NEXT FILTER ***
RETURN u
Are there any performance considerations by applying multiple filters at once
on databases with a large amount of user nodes?
As I understand it would be necessary to create an index on the name property for the Hobby and CharacterDetail nodes.
Normally, indexes are useful when they are directly specified in the WHERE clause, for example: n.id = 0. In your case, you already collected the name for each nodes so I don't think there will be any improvments but you can still try