2016-03-22 2 views
1

Wir haben Elemente in unserer App, die eine baumartige Struktur bilden. Sie könnten ein Muster wie die folgenden haben:Aktivitätsfeeds mit Rollups

(c:card)-[:child]->(subcard:card)-[:child]->(subsubcard:card) ... etc

Jedes Mal, wenn eine Operation auf einer Karte (auf jeder Ebene) durchgeführt wird, würden wir es aufnehmen möchten. Hier sind einige mögliche Ereignisse:

  • Der Titel einer Karte wurde von Bob aktualisiert
  • wurde ein Kommentar hinzugefügt von Kate Erwähnens Joe
  • Der Status einer Karte geändert von anhängigen genehmigt

Der Ansatz der verketteten Liste scheint populär zu sein, aber angesichts der Art von Anfragen, die wir gerne ausführen würden, bin ich mir nicht sicher, ob das für uns am besten funktioniert.

Hier sind die wichtigsten Abfragen wir laufen werden:

durch die Zeit des Ereignisses mit einer bestimmten Karte und Kind Karten, sortiert assoziiert
  • die gesamte Aktivität (im Grunde wie wir würden alle diese fusionieren Aktivität Feeds zusammen)
  • alle Aktivitäten mit einer bestimmten Person sortiert nach Zeit assoziiert

hinzu kommt, dass wir möchten, dass Filter hinzufügen wie folgt aus:

  • Filtern Person beteiligt
  • Filtern Zeitraum

Es ist auch wichtig zu beachten, dass die Karten neu arrangiert sehr häufig werden kann. Mit anderen Worten, die Eltern können sich ändern.

Irgendwelche Ideen, wie man so etwas am besten modelliert? Vielen Dank!

Antwort

0

Ich habe ein paar Vorschläge, aber ich würde vorschlagen, sie zu vergleichen.

Der Ansatz der verketteten Liste ist möglicherweise gut, wenn Sie die Java-APIs verwenden könnten (möglicherweise über eine nicht verwaltete Erweiterung für Neo4j). Wenn das neueste Ereignis in der Liste dasjenige war, das an die Karte angehängt war (und die Liste im Wesentlichen nach dem Datum sortiert war, an dem die Ereignisse stattfanden), dann könnten Sie, wenn Sie nach Zeit filtern, vorzeitig beenden, wenn Sie ein gefunden haben Ereignis, das vor der angegebenen Zeit liegt.

Das direkte Anhängen der Ereignisse an die Karte kann zu Problemen mit Superknoten/dichten Knoten führen. Es wäre jedoch am einfachsten, in Cypher nachzufragen. Das Problem ist, dass Cypher sie alle vor dem Filtern betrachten wird. Sie könnten die Leistung von Abfragen möglicherweise verbessern, indem Sie das Datum/die Uhrzeit des Ereignisses auf dem Ereignisknoten platzieren und auf die Beziehungen zum Knoten setzen ((:Card)-[:HAS_EVENT]->(:Event) oder (:Event)-[:PERFORMED_BY]->(:Person)). Wenn Sie dann eine Abfrage durchführen, können Sie nach den Beziehungen filtern, so dass sie nicht zu den Knoten durchlaufen muss.

Egal, wäre es wahrscheinlich hilfreich sein, die Abfrage wie so zu brechen:

MATCH (c:Card {uuid: 'id_here')-[:child*0..]->(child:Card) 
WITH child 
MATCH (child)-[:HAS_EVENT]->(event:Event) 

ich denke das würde bedeuten, dass die MATCH weniger Permutationen von Pfaden haben wird, die es benötigt, um zu bewerten .

Andere sind willkommen meine fragwürdigen Ratschläge zu ergänzen, wie ich habe nie wirklich persönlich mit Superknoten behandelt, nur um sie zu lesen;)

+0

Dank Brian :) Ist durch Bereich Indizes Neo4j ermöglichen sortieren.? Wenn ich beispielsweise Zeitstempel für Ereignisknoten hätte, wäre ich in der Lage, Ereignisse, die innerhalb eines bestimmten Zeitbereichs liegen und 2. dem Kind angehören, effizient abzufragen? –

+0

Neo4j kann auf jeden Fall Indizes verwenden, um schnellere Abfragen nach Bereichen durchzuführen (beginnend mit 2.3). Der Trick besteht darin, sicherzustellen, dass es herausfinden kann, welcher der begrenzendste Startort ist. Wenn Sie denken, dass die Filterung nach Ereignisdaten Ihnen den kleineren Startpunkt geben wird, können Sie stattdessen mit "MATCH" auf Ereignissen beginnen. –