Return node if no relationship

I am trying to create a request using cypher that will "detect" the missing components that the chef may have. My graph is set up like this:

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

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

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

I use this query to get all ingredients , but not their actual values ​​that are required for the recipe, but I would like to return only the ingredients that the chef does not have, instead of all the ingredients needed for each recipe. I tried

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

but it didn’t return anything.

Is this something that cypher / neo4j can do, or is it something that is best handled by returning all the ingredients and sorting them yourself?

Bonus: There is also a way to use cypher to match all the values ​​that the cook has for all the values ​​that the recipe requires. So far, I have returned all partial matches returned by chef-[:has_value]->ingredient_value<-[:requires_value]-recipe and aggregating the results myself.

+49
neo4j cypher
Jun 08 2018-12-12T00:
source share
6 answers

Update 01/10/2013:

Navigated through the Neo4j 2.0 link:

Try not to use additional relationships. Primarily,

do not use them as follows:

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

Instead, do the following:

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



Using cypher to check if a relationship exists:

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

What? mark makes communication optional.

OR

In neo4j 2 do:

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

Now you can check for nonexistent (null) relationships.

+103
Jan 10 '13 at 9:09
source share

To select nodes that are not related

This is a good option for checking whether or not a relationship exists.

 MATCH (player)-[r:played]->() WHERE r IS NULL RETURN player 

You can also check several conditions for this. He will return all nodes that do not have a “played” or “unladen” relationship.

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

Get nodes that have no reality

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

It will check the node for the lack of inbound / outbound relationships.

+10
Dec 08 '14 at 7:31
source share

If you need the semantics of conditional exclusion, you can achieve this in this way.

As with neo4j 2.2.1, you can use the OPTIONAL MATCH and filter out unsurpassed ( NULL ) nodes.

It is also important to use the WITH clause between the OPTIONAL MATCH and WHERE OPTIONAL MATCH , so that WHERE behaves as a filter, and not as part of a matching pattern.

Assuming we have 2 types of nodes: Person and Communication . If I want to receive all Persons who have never talked on the phone, but who may have exchanged in other ways, I would make this request:

 MATCH (p: Person) OPTIONAL MATCH p--(c: Communication) WHERE c.way = 'telephone' WITH p, c WHERE c IS NULL RETURN p 

Note that the first WHERE behaves exactly the same as part of the match.

Literature:

http://neo4j.com/docs/stable/query-optional-match.html#_introduction_3 http://java.dzone.com/articles/new-neo4j-optional

+5
May 08 '15 at 1:25
source share

I accomplished this task using gremlins. I did

 x=[] g.idx('Chef')[[name:'chef1']].as('chef') .out('has_ingredient').as('alreadyHas').aggregate(x).back('chef') .out('has_value').as('values') .in('requires_value').as('recipes') .out('requires_ingredient').as('ingredients').except(x).path() 

This returned the path of all the missing ingredients. I could not formulate this in cypher, at least for version 1.7.

+2
Jun 11 '12 at 7:12
source share

I wrote an essence showing how this can be done quite naturally using Cypher 2.0

http://gist.neo4j.org/?9171581

The key point is to use the optional matching of available ingredients and then compare with filters for missing (zero) ingredients or ingredients with the wrong value.

Please note that the concept is declarative and does not need to describe the algorithm, you just write down what you need.

+2
Feb 23 '14 at 14:13
source share

Last request should be:

 START chef = node(..) MATCH (chef)-[:has_value]->(ingredient_value)<-[:requires_value]-(recipe)-[:requires_ingredient]->(ingredient) WHERE (ingredient)<-[:has_ingredient]-chef RETURN ingredient 

This pattern: (ingredient)<-[:has_ingredient*0..0]-chef

Is the reason she didn’t return anything. *0..0 means that the length of the relationship must be zero, which means that the ingredient and the chef must be the same node, which they are not.

+1
Jun 09
source share



All Articles