Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Return node if relationship is not present

Tags:

neo4j

cypher

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.

like image 283
Nicholas Avatar asked Jun 08 '12 16:06

Nicholas


2 Answers

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.

like image 79
Gil Stal Avatar answered Sep 20 '22 17:09

Gil Stal


For fetching nodes with not any relationship

This is the good option to check relationship is exist or not

MATCH (player)     WHERE NOT(player)-[:played]->()     RETURN player 

You can also check multiple conditions for this It will return all nodes, which not having "played" Or "notPlayed" Relationship.

MATCH (player)   WHERE NOT (player)-[:played|notPlayed]->()  RETURN player 

To fetch nodes which not having any realtionship

MATCH (player)  WHERE NOT (player)-[r]-() RETURN player 

It will check node not having any incoming/outgoing relationship.

like image 38
Satish Shinde Avatar answered Sep 21 '22 17:09

Satish Shinde