Return node if relationship is not present

Nicholas picture Nicholas · Jun 8, 2012 · Viewed 73k times · Source

I'm trying to create a query using cypher that will "Find" missing ingredients that a chef might have, My graph is set up like so:

(ingredient_value)-[:is_part_of]->(ingredient)

(ingredient) would have a key/value of name="dye colors". (ingredient_value) could have a key/value of value="red" and "is part of" the (ingredient, name="dye colors").

(chef)-[:has_value]->(ingredient_value)<-[:requires_value]-(recipe)-[:requires_ingredient]->(ingredient)

I'm using this query to get all the ingredients, but not their actual values, that a recipe requires, but I would like the return only the ingredients that the chef does not have, instead of all the ingredients each recipe requires. I tried

(chef)-[:has_value]->(ingredient_value)<-[:requires_value]-(recipe)-[:requires_ingredient]->(ingredient)<-[:has_ingredient*0..0]-chef

but this returned nothing.

Is this something that can be accomplished by cypher/neo4j or is this something that is best handled by returning all ingredients and sorted through them myself?

Bonus: Also is there a way to use cypher to match all values that a chef has to all values that a recipe requires. So far I've only returned all partial matches that are returned by a chef-[:has_value]->ingredient_value<-[:requires_value]-recipe and aggregating the results myself.

Answer

Gil Stal picture Gil Stal · Jan 10, 2013

Update 01/10/2013:

Came across this in the Neo4j 2.0 reference:

Try not to use optional relationships. Above all,

don’t use them like this:

MATCH a-[r?:LOVES]->() WHERE r IS NULL where you just make sure that they don’t exist.

Instead do this like so:

MATCH a WHERE NOT (a)-[:LOVES]->()

Using cypher for checking if relationship doesn't exist:

...
MATCH source-[r?:someType]-target
WHERE r is null
RETURN source

The ? mark makes the relationship optional.

OR

In neo4j 2 do:

...
OPTIONAL MATCH source-[r:someType]-target
WHERE r is null
RETURN source

Now you can check for non-existing (null) relationship.