93 votes

Renvoyer le nœud si la relation n'est pas présente

J'essaie de créer une requête à l'aide de cypher pour "trouver" les ingrédients manquants qu'un chef pourrait avoir. Mon graphique est configuré comme suit :

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

(ingredient) aurait une clé/valeur de name="dye colors". (ingredient_value) pourrait avoir une clé/valeur de valeur="rouge" et "fait partie" de l'élément (ingredient, name="dye colors") .

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

J'utilise cette requête pour obtenir toutes les ingredients mais pas leurs valeurs réelles, ce qui est nécessaire pour une recette, mais je voudrais que le retour ne concerne que les éléments suivants ingredients que le chef n'a pas, au lieu de tous les ingrédients que chaque recette requiert. J'ai essayé

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

mais cela n'a rien donné.

Est-ce quelque chose qui peut être accompli par cypher/neo4j ou est-ce quelque chose qui est mieux géré en retournant tous les ingrédients et en les triant moi-même ?

Bonus : existe-t-il également un moyen d'utiliser Cypher pour faire correspondre toutes les valeurs que possède un chef à toutes les valeurs requises par une recette. Jusqu'à présent, je n'ai renvoyé que les correspondances partielles renvoyées par la fonction chef-[:has_value]->ingredient_value<-[:requires_value]-recipe et en agrégeant les résultats moi-même.

0 votes

Consultez ici les informations relatives à la v3 : stackoverflow.com/questions/25673223/

0 votes

Pour les futurs utilisateurs, vous pouvez utiliser exists dans un WHERE (la nier également), neo4j.com/developer/subqueries/#existential-subqueries pour plus d'informations.

164voto

gil Points 679

Mise à jour 01/10/2013 :

J'ai trouvé ceci dans le site de Neo4j. 2.0 référence :

Essayez de ne pas utiliser de relations facultatives. Surtout,

ne les utilisez pas comme ça :

MATCH a-[r?:LOVES]->() WHERE r IS NULL où vous vous assurez juste qu'ils n'existent pas.

Faites plutôt comme ceci :

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

Utilisation du cryptage pour vérifier si la relation n'existe pas :

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

Le signe ? rend la relation facultative.

OU

Dans neo4j 2 faire :

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

Vous pouvez maintenant vérifier si la relation est inexistante (nulle).

3 votes

Dans Neo4j 2.0, utilisez OPTIONAL MATCH pour faire correspondre des relations optionnelles, c'est-à-dire que le premier exemple ressemblerait à OPTIONAL MATCH (source)-[r:someType]-(target) RETURN source, r

0 votes

J'essaie d'avoir un nœud étiqueté dans WHERE NOT, mais cela ne fonctionne pas. Par exemple : MATCH a WHERE NOT (a)-[:LOVES]->(Stranger), dans ce cas 'Stranger' est une étiquette de noeud. J'utilise la version 2.1.2 de neo4j.

1 votes

C'est pas grave, je comprends pourquoi tu veux montrer la progression pour arriver à cette réponse : MATCH a WHERE NOT (a)-[:LOVES]->()

18voto

Satish Shinde Points 730

Pour récupérer les nœuds sans aucune relation.

C'est une bonne option pour vérifier si la relation existe ou non.

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

Vous pouvez également vérifier plusieurs conditions pour cela Il retournera tous les nœuds qui n'ont pas de relation "played" ou "notPlayed".

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

Pour récupérer les noeuds qui n'ont pas de relation entre eux.

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

Il vérifiera que le nœud n'a pas de relation entrante/sortante.

4 votes

MATCH (player) WHERE NOT (player)-[r]-() RETURN player donne Variable r non définie erreur. Comment puis-je définir r ?

0 votes

Pour résoudre ce problème, il faut soit spécifier une relation (par ex. (player -[:rel]- () ) ou laisser vide pour toute relation (player -[]- ()

0 votes

MATCH (player) WHERE NOT (player)-[]-() RETURN player - Il fonctionne bien

8voto

Dieter Pisarewski Points 708

Si vous avez besoin de la sémantique "exclusion conditionnelle", vous pouvez l'obtenir de cette façon.

À partir de neo4j 2.2.1, vous pouvez utiliser les éléments suivants OPTIONAL MATCH et filtrer les clauses non correspondantes( NULL ).

Il est également important d'utiliser WITH entre le OPTIONAL MATCH y WHERE de sorte que la première WHERE définit une condition pour la correspondance facultative et la seconde WHERE se comporte comme un filtre.

Supposons que nous ayons 2 types de noeuds : Person y Communication . Si je veux obtenir toutes les personnes qui n'ont jamais communiqué par téléphone, mais qui ont pu communiquer par d'autres moyens, je ferai cette requête :

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

Le modèle de correspondance correspondra à toutes les personnes et à leurs communications dans les cas suivants c sera NULL pour les communications non téléphoniques. Ensuite, le filtre( WHERE après WITH ) filtrera les communications téléphoniques en laissant toutes les autres.

Références :

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

2voto

Nicholas Points 4169

J'ai réalisé cette tâche en utilisant gremlin. J'ai fait

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()

Cela a renvoyé les chemins de tous les ingrédients manquants. Je n'ai pas réussi à formuler cela dans le langage de chiffrement, du moins pour la version 1.7.

2voto

boggle Points 171

J'ai écrit un gist montrant comment cela peut être fait tout naturellement en utilisant Cypher 2.0.

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

Le point essentiel est d'utiliser la correspondance facultative avec les ingrédients disponibles, puis de comparer pour filtrer les ingrédients manquants (nuls) ou les ingrédients dont la valeur est erronée.

Notez que la notion est déclarative et n'a pas besoin de décrire un algorithme, il suffit d'écrire ce dont on a besoin.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X