2016-07-21 12 views
3

Filterung Ich habe eine Chiffre-Abfrage, die so etwas wie ist:Meine Chiffre WHERE-Klausel nicht

MATCH(e:ZOOT {id:100}) 
OPTIONAL MATCH(e)-[a1]->(X:QAZ) 
OPTIONAL MATCH(e)-[a2]->(Y:WSX) 
WHERE a1 is not null or a2 is not null 
RETURN e, a1, a2 

Was ich will, ist für die Zeilen produzieren weder a1 oder a2 zu weggefiltert werden.

Noch meine Anweisung gibt Zeilen in allen Fällen zurück, auch von a1 und a2 sind beide null.

Wie funktioniert WO wirklich?

bearbeiten - Klärung hinzugefügt

+0

Möglicherweise möchten Sie die Dokumentation zur Verwendung von Beschriftungen und zum Abgleich mit Beziehungen in Abfragen erneut lesen. Im Augenblick sind e, a1, a2, X und Y alle Variablen, und Sie verwenden in Ihrer Abfrage keine Label- oder Beziehungsnamen, so dass es mit jedem einzelnen Ding in Ihrer db übereinstimmt, das einen beliebigen Knoten hat der Beziehung zu einem anderen Knoten. Außerdem haben Sie die Variable a nie definiert. Wenn Sie also versuchen, sie zurückzugeben, wird ein Fehler erzeugt. – InverseFalcon

+0

Ganz richtig @InverseFalcon. Dies ist ein Beispiel. Die Interaktion von WHERE, 'a1' und' a2' interessiert mich.Genauso habe ich ein wenig mehr hinzugefügt, um die Klarheit zu verbessern. –

Antwort

4

der Grund, warum Sie verwirrend Ergebnisse sind zu sehen ist, weil Sie die WHERE gehen davon gilt für das gesamte Ergebnis, bevor es von RETURN abgepumpt wird. Dies ist jedoch nicht der Fall.

Aus der Dokumentation auf Cypher Structure:

WO: Nicht eine Klausel in seinem eigenen Recht, sondern Teil MATCH, OPTIONAL MATCH und MIT. Fügt einem Muster Bedingungen hinzu oder filtert das Zwischenergebnis , das durch WITH läuft.

Also, wenn ich stelle Klammern, wie die Klauseln Gruppe zusammen zu zeigen, es würde wie folgt aussehen:

MATCH (e:ZOOT {id:100}) 
OPTIONAL MATCH(e)-[a1]->(X:QAZ) 

(OPTIONAL MATCH(e)-[a2]->(Y:WSX) 
WHERE a1 is not null or a2 is not null) 

RETURN e, a1, a2 

Ihre WHERE nur für dieses OPTIONAL MATCH bewirbt (das wird insbesondere OPTIONAL MATCH nur dann angezeigt, wenn a1 nicht null ist oder a2 nicht null ist), was nicht deine Absicht war. Sie wollen es die ganze Sache gelten, so ist der einfachste Weg, das zu tun ist, um die Abfragen mit einer WITH zu trennen etwa so:

MATCH (e:ZOOT {id:100}) 
OPTIONAL MATCH(e)-[a1]->(:QAZ) 
OPTIONAL MATCH(e)-[a2]->(:WSX) 
WITH e, a1, a2 
WHERE a1 is not null or a2 is not null 
RETURN e, a1, a2 

Es ist ein Weg, um diese Abfrage ein wenig zu optimieren, wenn Sie nicht wirklich sind Sie interessieren sich für die Beziehungen selbst und möchten nur wissen, ob Ihr: ZOOT-Knoten eine Übereinstimmung mit einem QAZ-Knoten oder einem WSX-Knoten aufweist. Sie können wie exists() verwenden, so:

MATCH (e:ZOOT {id:100}) 
WHERE EXISTS((e)-->(:QAZ)) OR EXISTS((e)-->(:WSX)) 
RETURN e 

Beachten Sie, dass, da Sie nicht den Beziehungstyp vorsah oder die X- und Y-Variablen sind an die Endknoten gebunden verwenden, ich nehme an, Sie sind nicht daran interessiert Sie; Ich habe sie entfernt, um Verwirrung beim Lesen Ihrer Suchanfrage zu vermeiden.

+0

Danke. Ich hatte eine vage Erinnerung an das Verhalten von wo, konnte es aber in der Dokumentation nicht finden. Auf jeden Fall dachte ich nicht daran, es mit _with_ zu lösen. Und _exists_ ist besser als was ich tat. –

+0

Arbeitete wie ein Champion. –

1

Sie abfragen können Ihre Anfrage an diesem

Spiel (e) ändern - [r: a1 | a2] - (x) return e, r, x

wie für die WHERE-Klausel ich hasse, das offensichtliche zu erklären, aber lesen this :)