2016-07-25 11 views
0

Innerhalb einer Grafik gibt es eine Gruppe G1 - diese Gruppe G1 hat 3 Untergruppen S1, S2 und S3. Die Beziehung wird als IS_SUBGROUP_OF klassifiziert. G1 selbst ist wieder eine Untergruppe einer anderen Gruppe, nennen wir es D1. D1 hat viele Untergruppen, wobei G1 nur eins ist.Fahrgraph nur innerhalb einer Ebene

Einen Benutzer U1 haben, der Mitglied einer Untergruppe von G1 ist - hier S1. Ich möchte eine Abfrage erstellen, die in der Lage ist, alle Benutzer der Untergruppe S1 zu sammeln, von Benutzer U1 nach S1 und von dort nach G1 zu gehen, die Benutzer von G1 und von G1 nach S2 und S3 zu holen und alle Benutzer von S2 und S3 zu holen auch. Das Endergebnis sollte alle Benutzer in den Untergruppen S1, S2 und S3 von der Elterngruppe G1 einschließlich der Benutzer von G1 sein.

Ich habe versucht:

MATCH (d:User) --> (S1:Subgroup)-[:IS_SUBGROUP_OF*0..]->(G1:Group) 
WHERE d.name = "U1" 
RETURN d 

Leider queren ich alle Gruppen und geben wieder alle Benutzer einer Gruppe in der Grafik. Ich habe versucht, die Sprunghöhe in der Beziehung zu ändern (z. B. nur 1), aber es ist nicht gelungen. Haben Sie einen Hinweis, wie Sie die Abfrage erstellen, um nur diese Teilmenge von Benutzern zu erhalten?

Die Namen der Gruppen sind nur für das Beispiel und nicht in der realen Welt bekannt - alles was ich weiß ist der Benutzername (hier: U1) - und von dort muss ich verschiedene Gruppen finden je nachdem, wo der Benutzer ist. In der Abfrage kann ich also nicht mit Namen von Gruppen arbeiten, sondern nur mit Variablen, da diese nicht bekannt sind.

* EDITED *

Sorry für die Verwirrung, labeld I S1 fälschlicherweise als Untergruppe, sondern nur die Beziehung erwähnt 'IS_SUBGROUP_OF', so dass alle Gruppenknoten haben die Bezeichnung 'Gruppe', D1 würde auch die Label 'Gruppe'. Ich füge auch das Beziehungslabel für Benutzer hinzu, so sieht die Aussage jetzt so aus:

MATCH (d:User) -[:IS_MEMBER_OF]-> (S1:Group)-[:IS_SUBGROUP_OF*0..]->(G1:Group) 
WHERE d.name = "U1" 
RETURN d 
+0

S1, S2, S3 haben die Bezeichnung "Untergruppe", G1 hat "Gruppe", was ist mit D1? Und wie heißt die Beziehung zwischen einer (Unter-) Gruppe und einem Benutzer? Können Sie die Frage damit aktualisieren? –

+0

Ich korrigierte und erweiterte die Abfrage von meiner Frage. – Balael

Antwort

1

Diese Antwort nimmt der Benutzer als ein Mitglied einer Gruppe von der IS_MEMBER_OF Beziehung identifiziert wird.

Die Abfrage ermittelt zuerst die übergeordnete Gruppe G1 basierend auf dem angegebenen Benutzer U1. Es ermittelt dann alle Benutzer der untergeordneten Gruppen G1 (S1, S2, S3) und gibt die Auflistung der einzelnen Benutzer über die untergeordneten Gruppen zurück.

Dies ist ein etwas verallgemeinertes Verfahren, mit dem mehr Ebenen durchlaufen werden können, indem die Anzahl der zu durchquerenden Ebenen in jeder Situation geändert wird.

// follow IS_MEMBER_OF or IS_SUBGROUP_OF relationships up 
// the group/user hierarchy to find the parent group two 
// levels up 
match (u:User1 {name: 'U1'})-[:IS_MEMBER_OF|IS_SUBGROUP_OF*2]->(g:Group) 

// using the parent group 
with g 

// follow the IS_MEMBER_OF or IS_SUBGROUP_OF relationships back down 
// the hierarchy to find all of the peer users or the original user  
match (g)<-[:IS_MEMBER_OF|IS_SUBGROUP_OF*2]-(u:User) 
return collect(distinct u) 
+0

Danke für diesen Ansatz. Ich versuche mich an die Mit-Klausel zu erinnern, da ich nicht verstanden habe, warum wir in der Beziehung zwischen Benutzer und Gruppe die Bezeichnung 'IS_SUBGROUP_OF' haben. Das Gefühl ist, dass Übereinstimmung (u: Benutzer {Name: 'U1'}) - [: IS_MEMBER_OF] -> (g: Gruppe) mit g übereinstimmen (g) <- [: IS_MEMBER_OF] - (u: Benutzer) return collect (distinct u) gibt das gleiche Ergebnis? Auch die Abfrage geht bis zu D1 und sammelt Benutzer von der nächsten Gruppe von Untergruppen (nennen wir sie X1 mit XS1, XS2, XS3), was nicht beabsichtigt war. Struggling :) – Balael

+0

Seltsam ... soweit ich das beurteilen kann, sollte diese Abfrage funktionieren. Es ist ein bisschen verwirrend mit dem OR-Abgleich auf Beziehungsbezeichnungen mit Grad 2, aber es sollte den Job erledigen ... – InverseFalcon

+0

Ich habe ein Test-Diagramm erstellt und beide sind korrekt, es funktioniert wie beschrieben. In meinem ursprünglichen Diagramm scheint ein Fehler zu liegen. Also die Abfrage ist richtig - vielen Dank! – Balael

0

Würde das funktionieren?

MATCH (d:User)-[*0..1]-(G1:Group) 
WHERE d.name= 'U1' 
RETURN DISTINCT d 
+1

Hallo, vielen Dank für die Eingabe.Ich würde annehmen, solange wir Benutzer in der Where-Klausel namentlich abfragen, erhalten wir genau diesen Benutzer, egal wie viele Gruppen und Benutzer beteiligt sind. – Balael

2

Lassen Sie uns dies versuchen, eine kleine zwicken auf Daves Antwort (die gut funktionieren sollte so weit wie ich kann sagen ...)

MATCH (:User {name: 'U1'})-[:IS_MEMBER_OF]->(:Group)-[:IS_SUBGROUP_OF]->(superGroup:Group) 
WITH superGroup 
MATCH (superGroup)<-[:IS_SUBGROUP_OF*0..1]-(:Group)<-[:IS_MEMBER_OF]-(users:User) 
RETURN COLLECT(DISTINCT users) 

auf dem Startbenutzer Basierend dies die Großeltern findet Gruppe oder Supergroup (G1 gemäß Ihrem Beispiel), dann passt auf Benutzer, die Mitglied von G1 oder einer seiner unmittelbaren Untergruppen sind, und gibt die eindeutige Auflistung zurück. Es enthält den ursprünglichen übereinstimmenden Benutzer.

+0

Hallo, großartig, das bringt mein Wissen ein bisschen weiter, da ich weiß auch eine Lösung wie man die überlegene Gruppe einbinden kann. Sehr hilfreich. – Balael