Neo4j – Mehrfache Gruppenverschachtelungen auflösen

Es gibt immer wieder die Fälle, dass es zwischen Gruppen mehrfache Verbindungen gibt. Entweder ist die Gruppe

 

A-B

A-C-B

A-c-D-B

 

Die zentrale Frage ist, wie man eigentlich in solchen Fällen vorgeht?

Eine Möglichkeit wäre die Auflösung der Mitgliedschaften, bis nur noch die längste Verbindung bestehen bleibt oder umgedreht.

 

In diesem Fall gab es sehr tiefe Verschachtelungen von Gruppen über 8 Ebenen

Es musste die erste und die Letzte Gruppe ausgelesen werden, um diese dann über Powershell direkt zu verbinden und die Zwischenhobs aufzulösen

 

Ablauf

  1. Anzahl der Verschachtelungen mit Tiefe gesamt ohne redundanzen nur auf Gruppenbasis
Anzahl count(Anzahl)
1 28965
2 73176
3 45026
4 67704
5 95035
6 65511
7 18131
8 1689

 

Anzahl der Gruppenbeziehungen gesamt

MATCH p=(n)<-[:rel_member*1..]-(g:ADAccount) where g.type="group" and n.type="person"

with length((p)) as Anzahl, n.domain as domain RETURN distinct count(Anzahl)

 

 

count(Anzahl)
395237

Redundante Gruppenbeziehungen zählen

MATCH p=((n:ADAccount)<-[r:rel_member*1..]-(root)) where not n.domain='local'
 and n.type='group' and root.type='group' with count(distinct p) as Anzahl_Verbindungen 
where Anzahl_Verbindungen>1 RETURN distinct Anzahl_Verbindungen

 

Anzahl_Verbindungen
79428

 

Redundante Gruppen auflisten

MATCH p=((n:ADAccount)<-[:rel_member*1..]-(root)) where not n.domain='local' 
and n.type='group' and not n=root and root.type='group' with n,root,count
(distinct p) as Anzahl_Verbindungen where Anzahl_Verbindungen>1 MATCH p=((n)
<-[:rel_member*1..]-(root)) RETURN distinct n.name,extract(node in nodes(p)[1..-1]
|node.name) as hops,root.name, (length(p)-1) as Anzahl_Hops,Anzahl_Verbindungen order 
by n.name,root.name,hops, Anzahl_Hops,Anzahl_Verbindungen desc

 

 

n.name hops root.name Anzahl_Hops Anzahl_Verbindungen
„1st-level“ [] „applsql-altiris-readall“ 0 2
„1st-level“ [„altiris readers“] „applsql-altiris-readall“ 1 2
„2nd-level“ [] „applsql-altiris-fullall“ 0 2
„2nd-level“ [„altiris workers el“] „applsql-altiris-fullall“ 1 2
„2nd-level“ [„1st-level“] „applsql-altiris-readall“ 1 2
„2nd-level“ [„1st-level“, „altiris readers“] „applsql-altiris-readall“ 2 2
„2nd-level“ [„1st-level“] „exchange view-only administrators“ 1 2
„2nd-level“ [„exchange recipient administrators“] „exchange view-only administrators“ 1 2
„2nd-level“ [] „g_tsx-shadowing“ 0 2

Alle Verbindungen die einzigartig sind werden in der DB markiert

MATCH p=((n:ADAccount)<-[:rel_member*..]-(root)) where not n.domain='local' 
and n.type='group' and not n=root and root.type='group' with n,root,count
(distinct p) as Anzahl_Verbindungen where Anzahl_Verbindungen=1 MATCH p= 
((n)<-[r:rel_member*..]-(root)) with r unwind(r) as kanten set kanten.only=1

Visualisierung der zukünftigen Beziehungen

MATCH p=((n:ADAccount)<-[r:rel_member*1..]-(root)) where not r.only=1 and 
not n.domain='local' and n.type='group' and not n=root and root.type='group' 
with n,root,count(distinct p) as Anzahl_Verbindungen where Anzahl_Verbindungen>
1 MATCH p=((n)<-[r:rel_member*1..]-(root)) where not r.only=1 and RETURN distinct 
n.name,extract(node in nodes(p)[1..-1]|node.name) as hops,root.name, (length(p)-1) 
as Anzahl_Hops,Anzahl_Verbindungen order by n.name,root.name,hops, Anzahl_Hops,Anzahl_Verbindungen desc

 

 

Alle nicht markierten Verbindungen werden exportiert (Gruppe – Gruppe), um sie dann per PS auflösen zu können

In diesem Fall 553 Beziehungen, die aufgelöst werden können und die Übersicht verbessern

optional MATCH p=((n:ADAccount)<-[r:rel_member]-(root)) where not 
n.domain='local' and n.type='group' and root.type='group' and r.only 
is null RETURN distinct n.name,root.name, r.only

 

n.name root.name r.only
„g_ecm_a-331 elektrotechnik_band_härtelinien_turmöfen“ „g_xecm“ null
„g_ecm_a-833 interne personalservices“ „g_xecm“ null
„g_ecm_a-361 inbetriebsetzung“ „g_xecm“ null
„g_ecm_a-333 elektrotechnik_haubenöfen“ „g_xecm“ null
„g_ecm_a-335 elektrotechnik_stoß-_kammeröfen“ „g_xecm“ null
„g_ecm_a-b0 technologie_und_realisierung“ „g_xecm“ null
„g_ecm_a-338 pps elektro-_und_automatisierungstechnik“ „g_xecm“ null
„g_ecm_a-91 projektmanagement_technische_realisierung“ „g_xecm“ null
„g_ecm_a-c2“ „g_xecm“ null
„g_ecm_a-33a visualisierung_und_prozessleitsysteme (cos_pcs)“ „g_xecm“ null
„g_ecm_a-31 normung_und_standardisierung“ „g_ecm_interarea_drawings_projectdrawing_m“ null
„g_ecm_a-31 normung_und_standardisierung“ „g_ecm_interarea_drawings_sparepartdrawing_m“ null

 

->>>>>> Powershell für die Auflösung der Gruppenbeziehungen

Alle nicht markierten Gruppenbeziehungen aus der DB entfernen

MATCH p=((n:ADAccount)<-[r:rel_member*..]-(root)) where not n.domain='local' 
and n.type='group' and not n=root and root.type='group' with r unwind(r) as 
kanten with kanten where kanten.only is null delete kanten

Zählen aller Gruppenbeziehungen nach der Löschung

MATCH p=(n)<-[:rel_member*1..]-(g:ADAccount) where g.type="group" and 
n.type="person" with length((p)) as Anzahl, n.domain as domain RETURN 
distinct count(Anzahl)

 

count(Anzahl)
353516

Permanentlink zu diesem Beitrag: https://help.migraven.com/neo4j-mehrfache-gruppenverschachtelungen-aufloesen/