Ich kann eine Alternative zum Aufbau Ihrer: WITH Beziehungen vorschlagen.
MATCH (c:Client)-[:ATTENDED]->(:Seminar)<-[:ATTENDED]-(co:Client)
WITH c, co, COUNT(co) as timesWith
MERGE (c)-[r:WITH]-(co)
SET r.count = timesWith
Diese Sie für jeden Kunden eine Reihe bekommt, einen Client sie Seminare besucht mit, und die Anzahl der Zeiten, die sie mit ihnen ein Seminar besucht, und speichert (oder Updates), die auf Ihrem zählen: MIT Beziehungen.
Sie können Ihre Abfrage für das Erstellen von Seminaren und die Beziehungen zwischen Clients und Seminaren viel einfacher machen, wenn Sie eine Sammlung von IDs als Parameter für Ihre Abfrage bereitstellen können, da Sie dies auf einmal statt einzeln tun können:
MATCH (c:Client), (s:Seminar {id: sid})
WHERE c.id IN {attendeeIDs}
MERGE (c)-[:ATTENDED]->(s)
// and then you can run the query above to update WITH relationships if necessary
Wie für den Rest von dem, was Sie wollen, ist das eine ziemlich knifflige Abfrage, und ich bin nicht sicher, ob Sie es klar gemacht haben, was sollte Ihr Ansatz.
Suchen Sie eine Reihe von 5: Clients wie die Summe der Zählungen der: WITH Beziehungen zwischen ihnen ist die größte von jeder anderen Gruppe von 5? Weil diese Art von Abfrage erfordert, dass Sie jede Kombination von 5 Clients testen und diese Berechnung durchführen müssen, und wir müssen auch besonders darauf achten, dass wir dies mit Kombinationen und nicht mit Permutationen tun.
Auch dann wird es sehr teuer Abfrage, da die Anzahl der Kombinationen von Sätzen von 5 von 70 Möglichkeiten ist C (70,5) = 12.103.014. Das ist eine Menge aufgebauter Zeilen und Operationen, die auf jeder einzelnen dieser Zeilen ausgeführt werden.
// first match on a combination of 5; id inequalities prevent permutations
MATCH (c1:Client), (c2:Client), (c3:Client), (c4:Client), (c5:Client)
WHERE id(c1) < id(c2) < id(c3) < id(c4) < id(c5)
WITH c1, c2, c3, c4, c5, [id(c1),id(c2),id(c3),id(c4),id(c5)] as ids
// find all possible :WITH relationships between each set of 5
OPTIONAL MATCH (a)-[r:WITH]-(b)
WHERE id(a) in ids AND id(b) in ids
WITH c1,c2,c3,c4,c5, SUM(r.count) as togetherness
ORDER BY togetherness DESC
RETURN c1,c2,c3,c4,c5
LIMIT 1
Es gibt Möglichkeiten, dies effizienter zu machen. Anstatt alle zu betrachten: Kunden, könnten Sie zuerst versuchen, das Top-n oder so zu bekommen: Clients basierend auf Seminaren besucht, und dann versuchen, eine ähnliche Abfrage auszuführen.
Dies ist, wie es aussehen könnte, wenn Sie den Top-15-Teilnehmer bis zum Seminar Teilnahme zuerst ausgewählt, dann versucht, die Gruppe von 5 zu finden, das gemeinsam von denen waren das Beste aus 15:
MATCH (c:Client)
WITH c, SIZE((c)-[:ATTENDED]->(:Seminar)) as attendance
ORDER BY attendance DESC
WITH c
LIMIT 15
WITH COLLECT(id(c)) as ids
// first match on a combination of 5; id inequalities prevent permutations
MATCH (c1:Client), (c2:Client), (c3:Client), (c4:Client), (c5:Client)
WHERE id(c1) in ids, id(c2) in ids, id(c3) in ids, id(c4) in ids, id(c5) in ids
AND id(c1) < id(c2) < id(c3) < id(c4) < id(c5)
WITH c1, c2, c3, c4, c5, [id(c1),id(c2),id(c3),id(c4),id(c5)] as ids
// find all possible :WITH relationships between each set of 5
OPTIONAL MATCH (a)-[r:WITH]-(b)
WHERE id(a) in ids AND id(b) in ids
WITH c1,c2,c3,c4,c5, SUM(r.count) as togetherness
ORDER BY togetherness DESC
RETURN c1,c2,c3,c4,c5
LIMIT 1