2016-07-14 8 views
0

Ich habe eine Abfrage, die von einer bestimmten Person ausgeht, und mit ein paar verschiedenen Methoden der Beziehung Traversal sammelt alle Interessierten: Person Knoten zusammen (deutlich), und gibt einen gemeinsamen Datensatz für jede dieser: Personen .Wie kann ich knotenbezogene Daten in einer komplexen Abfrage weitergeben, wenn ich Knoten sammle, kombiniere und abwickle?

Eines dieser Datenelemente spiegelt den Modus oder die Typen dieser Beziehung wider, und ich versuche herauszufinden, ob es eine Möglichkeit gibt, eine Flagge zu setzen, die diese Beziehung anzeigt: Personen in dieser Beziehung, und diese beibehalten flag, auch wenn ich sammle, addiere, abwickle, und markiere diese: Personen.

Als ein vereinfachtes Beispiel habe ich direkte: Freund Beziehungen zu: Personen, die sind leicht zu sammeln. Ich habe auch einen: WorkPlace-Knoten, der eine Person: WorksAt. Ich benutze dies, um meine Mitarbeiter zu finden, die sind: Personen, die auch: WorksAt das gleiche: WorkPlace.

Ich möchte einen Weg, um beide Ergebnisse zu kombinieren: Personen, um ein eigenes Set zu bekommen (alle meine Freunde kombiniert mit allen meinen Mitarbeitern, ohne Duplikate, wenn eine Person sowohl ein Freund als auch ein Kollege ist). Union wird mir nicht helfen, da dies keine Nachbearbeitung der Ergebnisse erlaubt. Stattdessen sammle ich separat beide Gruppen von Personen aus den Unterabfragen, füge sie zusammen, so dass sie alle in derselben Liste sind, entspanne sie und erhalte die verschiedenen Zeilen. Das funktioniert schon für mich.

An dieser Stelle habe ich jetzt alle: Personen, die ich interessiere, und ich kann Unterabfragen starten, um andere Knoten der Daten, die sie haben, die ich mit jeder Ausgabe Person Zeile aufnehmen möchten.

Eines dieser Datenelemente ist jedoch ein boolescher Wert, wenn: Person ein Kollege ist. Um dies zu erreichen, wiederhole ich einen Teil einer dieser Sammelfragen, um diese Beziehung zu überprüfen (funktioniert das: Person arbeite gleich: WorkPlace tue ich?) Und speichere sie als Boolean für die Ausgabe.

Das funktioniert gut ... aber ich fühle mich, als würde ich zusätzliche Arbeit leisten, dass es einen Weg geben sollte, einen booleschen isCoworker-Boolean zu kennzeichnen und zu bewahren, wenn ich das erste Mal finde. Das Ideal wäre es, diese Flagge irgendwo an den Knoten anzuhängen, damit sie die Collections() überlebt und abwickelt ... aber ich weiß nicht, wie ich das machen soll. Selbst wenn ich das könnte, glaube ich nicht, dass es den DISTINCT-Operator überleben würde (für dasselbe: Eine Person, die entdeckt wird als: Freund, diese Flagge wird nicht anwesend sein, und ich könnte eine ANDERE Flagge haben, ist Freund, dass ich möchte auch so das Ergebnis kombinieren: Die Person wird beide Flaggen haben). Ebenso glaube ich nicht, dass solch eine Flagge, die separat geschaffen wurde, auch alle diese Operationen überleben könnte.

Hat jemand anderes diese Art von Problem angetroffen (und hoffentlich gelöst)?

EDIT:

eine vereinfachte Version meiner Anfrage hinzufügen.

MATCH (me:Person{id:777}) 
WITH me 
OPTIONAL MATCH (me)-[:Friend]-(friend:Person) 
WITH me, collect(friend) AS friends 
OPTIONAL MATCH (me)-[:WorksAt]->[:WorkPlace]<-[:WorksAt]-(coworker:Person) 
WHERE coworker <> me 
WITH friends + collect(coworkers) AS everyone 
UNWIND everyone AS acquaintance 
WITH DISTINCT acquaintance 
// ... 
WITH acquaintance 
OPTIONAL MATCH (meAgain:Person{id:777})-[:WorksAt]->(:WorkPlace)<-[r:WorksAt]-(acquaintance) 
WITH meAgain, acquaintance, r IS NOT NULL AS isCoworker 
OPTIONAL MATCH (meAgain)-[r:Friend]-(acquaintance) 
RETURN acquaintance, isCoworker, r IS NOT NULL AS isFriend 

Auch dies ist vereinfacht. Am ... sammle ich Daten, die für jedes: Person-Objekt üblich sind, und lasse gerade die Weitergabe und Verwendung und Ausgabe dieser Daten im Rest der Abfrage aus, da sie nicht mit meinem Problem zusammenhängt. Auch gibt es mehrere Möglichkeiten zu sammeln: Personen, nicht nur diese zwei einfachen Beispiele.

Es ist die OPTIONALEN MATCHES, die ich versuche zu optimieren, indem ich irgendwie auf ähnliche Flags (isCoworker, isFriend) halte, aber zu der Zeit erstellt habe, als ich zu diesen passte: Personen. Diese Flags müssen in der Lage sein, die collect() -, list-addition-, unwinding- und distinct-Operationen zu überstehen.

+0

zeigen Ihre Anfrage! –

+0

Ich habe eine vereinfachte Version der Abfrage hinzugefügt, hoffe es hilft! – InverseFalcon

Antwort

1

Sie können einfach eine zweite Sammlung behalten, die die Mitarbeiter sind, und einen Scheck mit IN machen, um Ihren boolean zu bekommen, wo Sie ihn brauchen.

Als Beispiel modifizierte Abfrage:

MATCH (me:Person{id:777}) 
WITH me 
OPTIONAL MATCH (me)-[:Friend]-(friend:Person) 
WITH me, collect(friend) AS friends 
OPTIONAL MATCH (me)-[:WorksAt]->[:WorkPlace]<-[:WorksAt]-(coworker:Person) 
WHERE coworker <> me 
WITH friends, friends + collect(coworkers) AS everyone, collect(distinct coworker) AS coworkers 
UNWIND everyone AS acquaintance 
WITH DISTINCT acquaintance, coworkers, friends 
// ... 
WITH acquaintance, coworkers, friends 
WITH meAgain, acquaintance, acquaintance IN coworkers AS isCoworker 
RETURN acquaintance, isCoworker, acquaintance IN friends AS isFriend 
+0

Sieht gut aus, ich werde es versuchen! Schön, dass es eine einfache Lösung ist, danke! – InverseFalcon