Frage

Ich habe eine Anfrage wie diese:

MATCH left, right 
WHERE (ID(right) IN [1, 2, 3] AND ID(left) IN [4, 5, 6]) 
WITH left, right 
  LIMIT 1 
RETURN left, right 
UNION MATCH left, right 
WHERE (ID(right) IN [1, 2, 3] AND ID(left) IN [4, 5, 6]) 
WITH left, right 
  SKIP 4 LIMIT 1 
RETURN left, right 
UNION MATCH left, right 
WHERE (ID(right) IN [1, 2, 3] AND ID(left) IN [4, 5, 6]) 
WITH left, right 
  SKIP 8 LIMIT 1 
RETURN left, right
CREATE UNIQUE left-[rel:FRIEND]->right 
RETURN rel;

Im Allgemeinen erstelle ich nur einen Datensatz, damit ich ihn später in der CREATE UNIQUE-Anweisung verwenden kann.
Offensichtlich funktioniert das nicht – der Abfrageanalysator sagt, dass ich die RETURN-Klausel nur einmal verwenden kann.Meine Frage ist: Wie erstellt man in diesem Fall einen Datensatz?Ich habe versucht, einen Alias ​​zuzuweisen und ihn in CREATE UNIQUE zu verwenden, aber es funktioniert auch nicht.Was mache ich falsch?Ist dieses Szenario überhaupt möglich?

War es hilfreich?

Lösung

Vielleicht verstehe ich falsch, was Sie suchen, aber Folgendes fällt mir ein, wenn ich mir Ihre Anfrage ansehe.

Hier ist zunächst eine Anpassung Ihrer Abfrage, die verwendet wird SKIP Und LIMIT ohne RETURN oder UNION.

MATCH left, right
WHERE ID(left) IN [1,2,3] AND ID(right) IN [4,5,6]
WITH left, right 
    LIMIT 1
CREATE UNIQUE left-[rel:FRIEND]->right
WITH [rel] as rels  //If you want to return the relationship later you can put it in a collection and bring it WITH
MATCH left, right
WHERE ID(left) IN [1,2,3] AND ID(right) IN [4,5,6]
WITH left, right, rels 
    SKIP 4 LIMIT 1
CREATE UNIQUE left-[rel:FRIEND]->right
WITH rels + [rel] as rels
MATCH left, right
WHERE ID(left) IN [1,2,3] AND ID(right) IN [4,5,6]
WITH left, right, rels 
    SKIP 8 LIMIT 1
CREATE UNIQUE left-[rel:FRIEND]->right
WITH rels + [rel] as rels
RETURN LENGTH(rels), rels  // You can return the relationships here but SKIP/LIMIT does its job also if you don't return anything

Aber diese Abfrage ist etwas wild.Es handelt sich eigentlich um drei Abfragen, von denen zwei künstlich als Unterabfragen der ersten eingefügt wurden.Es gleicht dieselben Knoten in jeder Unterabfrage erneut ab, und es bringt wirklich nichts, wenn die Abfragen auf diese Weise und nicht einzeln ausgeführt werden (es ist tatsächlich langsamer, da Sie in jeder Unterabfrage auch die Knoten abgleichen, von denen Sie wissen, dass Sie sie nicht verwenden werden). .

Daher ist mein erster Vorschlag die Verwendung START anstatt MATCH...WHERE beim Abrufen von Knoten nach ID.So wie es aussieht, bindet die Abfrage jeden Knoten in der Datenbank als „links“ und dann jeden Knoten in der Datenbank als „rechts“ und filtert dann alle an „links“ gebundenen Knoten heraus, die nicht der Bedingung entsprechen Die WHERE Klausel und dann das Gleiche für „richtig“.Da dieser Teil der Abfrage dreimal wiederholt wird, werden alle Knoten in der Datenbank insgesamt sechsmal gebunden.Das ist teuer für den Aufbau von drei Beziehungen.Wenn du benutzt START Sie können die gewünschten Knoten sofort binden.Dies beantwortet Ihre Frage nicht wirklich, aber es geht schneller und die Abfrage wird sauberer.Also, verwenden START um Knoten anhand ihrer internen ID abzurufen.

START left = node(1,2,3), right = node(4,5,6)

Das zweite, woran ich denke, ist der Unterschied zwischen Knoten und „Pfaden“ oder „Ergebniselementen“, wenn Sie Muster abgleichen.Wenn Sie drei Knoten in „links“ und drei weitere Knoten in „rechts“ binden, haben Sie nicht drei Ergebniselemente, sondern neun.Für jeden „links“ gebundenen Knoten erhalten Sie drei Ergebnisse, da es drei mögliche „rechts“-Knoten gibt, mit denen er kombiniert werden kann.Wenn Sie jedes „Links“ mit jedem „Rechts“ in Beziehung setzen wollten, wäre das großartig.Aber ich denke, was Sie suchen, sind die Ergebniselemente (1),(4), (2),(5), (3),(6), und obwohl es praktisch erscheint, die drei „linken“ Knoten und die drei „rechten“ Knoten in einer Abfrage mit Sammlungen von Knoten-IDs zu binden, müssen Sie dann alle Filter durchführen, um die 6 unerwünschten Übereinstimmungen zu entfernen.Die Abfrage wird komplex und umständlich und ist tatsächlich langsamer als die separate Ausführung der Abfragen.Eine andere Möglichkeit, dies zu sagen, ist, jenes zu sagen (1)-[:FRIEND]->(4) ist ein eindeutiges Muster, das nicht (relevant) mit den anderen Mustern verbunden ist, die Sie erstellen.Es wäre anders, wenn Sie etwas erschaffen wollten (1)-[:FRIEND]->(2)<-[:FRIEND]-(3), dann möchten Sie diese drei Knoten gemeinsam behandeln.Vielleicht erforschen Sie nur Randanwendungen der Chiffre, aber ich dachte, ich sollte darauf hinweisen.Übrigens, mit SKIP Und LIMIT Auf diese Weise ist es etwas abwegig, sie sind eigentlich nicht für den Mustervergleich und die Filterung gedacht.Es ist auch unvorhersehbar, es sei denn, Sie verwenden es auch ORDER BY, da es keine Garantie dafür gibt, dass die Ergebnisse in einer bestimmten Reihenfolge vorliegen.Sie wissen nicht, welches Ergebniselement weitergeleitet wird.Wie auch immer, in diesem Fall wäre es meiner Meinung nach besser, die Knoten zu binden und die Beziehung in drei separaten Abfragen zu erstellen.

START left = node(1), right = node(4)
CREATE UNIQUE left-[rel:FRIEND]->right
RETURN rel

START left = node(2), right = node(5)
CREATE UNIQUE left-[rel:FRIEND]->right
RETURN rel

START left = node(3), right = node(6)
CREATE UNIQUE left-[rel:FRIEND]->right
RETURN rel

Da Sie bereits wissen, dass Sie diese drei Paare wollen, und nicht, sagen wir, (1),(4),(1),(5),(1),(6) Es wäre sinnvoll, nur nach diesen Paaren abzufragen. Am einfachsten ist es, sie separat abzufragen.

Aber drittens, da die drei Abfragen strukturell identisch sind und sich nur im Eigenschaftswert unterscheiden (wenn id als Eigenschaft betrachtet werden soll), können Sie die Abfrage vereinfachen, indem Sie das, was sie unterscheidet, verallgemeinern oder anonymisieren, d. h.Parameter verwenden.

START left = node({leftId}), right = node({rightId})
CREATE UNIQUE left-[rel:FRIEND]->right
RETURN rel

parameters: {leftId:1, rightId:4}, {leftId:2, rightId:5}, {leftId:3, rightId:6}

Da die Struktur identisch ist, kann Cypher den Ausführungsplan zwischenspeichern.Dies sorgt für eine gute Leistung, und die Abfrage ist übersichtlich, wartbar und kann leicht erweitert werden, wenn Sie später den gleichen Vorgang auf anderen Knotenpaaren durchführen möchten.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top