2016-07-07 7 views
0

Kann ich in neo4j einen Mechanismus zur Rückreferenzierung verwenden? Ich bin nicht daran interessiert, was der Abfrage entspricht, nur dass es an vielen Stellen dasselbe ist. Etwas wie:Zurück-Referenz neo4j

MATCH (a:Event {diagnosis1:11}) 
MATCH (b:Event {diagnosis1:15}) 
MATCH (c:Event {diagnosis1:5}) 
MATCH (a)-[rel:Next {PatientID:*}]->(b) 
MATCH (b)-[rel1:Next {PatientID:\{1}]->(c) 

Die Idee ist, dass ich benötige nur das Attribut IDs von beiden Kanten gleich zu sein, ohne es zu spezifizieren. Der ganze Zweck davon würde nicht alle möglichen Übereinstimmungen erzeugen, um sie dann zu filtern, sondern nur an bestimmten Orten zu springen.

Ich habe etwas auf eine spezifischere Art und Weise gefragt here.

Edit: Ich weiß, WHERE-Klauseln können dafür verwendet werden, aber sie filtern die Abfrage nach dem Abgleich der Kanten und Knoten. Ich will das WÄHREND des Matching tun!

Antwort

4

eine WHERE Klausel mit einfachen Referenzen verwenden, da für Rückverweise keine Notwendigkeit:

MATCH (a)-[rel:Next]->(b) 
MATCH (b)-[rel1:Next]->(c) 
WHERE rel.PatientID = rel1.PatientID 

aktualisieren

Zunächst einmal ist Cypher eine deklarative Abfragesprache: Sie sagen, was Sie wollen, die Laufzeit kümmert sich darum, sie auszuführen und zu optimieren, so dass es nicht so offensichtlich ist, dass es das tun würde, was Sie denken, oder dass die Verwendung von "Rückreferenzen" den Profi magisch lösen würde befleckt; es ist nur eine andere Art, dasselbe zu schreiben.

Ihr Problem besteht also darin, dass die Übereinstimmung alle Beziehungspaare erstellt, bevor sie gefiltert werden. Wie wäre es, das Spiel in 2 Phasen unter Verwendung WITH zu teilen?

MATCH (a:Event {diagnosis1:11})-[rel:Next]->(b:Event {diagnosis1:15}) 
WITH a, b, rel 
MATCH (b)-[rel1:Next]->(c:Event {diagnosis1:5}) 
WHERE rel1.PatientID = rel.PatientID 

, dass nur die zweite Beziehungen auswählen sollten, die das erste Spiel, aber ich bin nicht sicher, ob es sich um eine O (n^2) Algorithmus in Cypher Laufzeit ist.

Andernfalls, wenn Sie auf die Java-API fallen (die entweder eine Verlängerung oder ein Verfahren bedeuten würde, auf Ihre Version von Neo4j abhängig), können Sie wahrscheinlich von

in O (n) implementieren alle
  • Scannen die Beziehungen zwischen a und b, Indexierung von ihnen durch PatientID in einigen Multimap (siehe Guava, oder verwenden Sie eine); das ist O (n)
  • dann die gleiche zwischen b und c, noch O (n)
  • Iterierte auf den Tasten eines multimap für alle Beziehungen zu tun, die Werte in den beiden und passen sie, noch O zu erhalten (n)
+0

das ist nicht das, was ich will, wenn Sie das tun, generieren Sie alle Matchings und dann filtern dann! Es ist ineffizient! Ich möchte nicht alle Übereinstimmungen generieren, nur diejenigen, bei denen die IDs identisch sind. –

+0

Ich habe die Antwort basierend auf Ihrem zusätzlichen Kontext aktualisiert. –

+0

Vielen Dank! Ich frage mich, ob es etwas Material gibt, um die Java API zu ändern. Die Version mit "WITH" scheint nicht zu funktionieren: /. –