0

Versionen verwendet: Neo4j 3.0.6 mit Frühling-data-Neo4j 4.2.0.M1 für POJO MappingNeo4j Datenmodellierung: Privatbesitz Knoten, reiche Beziehungen, Schlösser

Ich versuche zu entscheiden, wie Daten zu modellieren mit neo4j und vergleichen Sie Vor- und Nachteile verschiedener Lösungen.

Anforderungen:

  • Ein Film eine dynamische Liste von Metadaten hat (ein Metadaten verfügt über 3 Eigenschaften: 'Schlüssel', 'Wert', 'locale'). Die Anzahl der Metadaten für einen Film ist nicht im Voraus bekannt, ebenso wenig wie die möglichen Schlüssel. Sie müssen von den anderen technischen Eigenschaften des Films trennbar sein, da sie lokalisiert sind und als Geschäftsdaten gelten.
  • Metadaten gehören dem Film und werden immer über den Film aufgerufen. Sie können nicht mit anderen Filmen
  • schnell geteilt werden, um Abfragen holen möglich auf Metadaten sein müssen Werte

Film Metadaten Beispiel:

Movie metadata 
    locale 'en_GB': 
    title: 'Jurassic Park' 
    description: 'description in english' 
    locale 'fr_FR': 
    description: 'description en francais' 
    locale 'none': 
    actor: 'Jeff Goldblum' 

enter image description here Lösung A

  • Ein Knoten pro Metadaten (mit 3 Eigenschaften pro Knoten: 'Schlüssel', 'Wert', 'Gebietsschema')
  • Nachteil: Privatbesitz Konzept umgesetzt werden (löschen von Metadaten verwaisten Knoten manuell verwaltet werden, weil nicht durch die Feder-data-Neo4j unterstützt/Neo4j-OGM)

Lösung B

  • Ein eindeutige Knoten pro locale (mit 1 Eigenschaft: 'locale') (Beispiel: 'de_AT')
  • Metadaten als reiche Beziehungen (mit 2 Beziehung properti es: ‚Schlüssel‘, ‚Wert‘)
  • Nachteil: die Beziehung zu erstellen, müssen eine Sperre auf Locale Knoten

Hat jemand hat Erfahrung über Lösung B eingenommen werden? Wie schlimm ist es, einen Knoten zu sperren, der von Millionen anderer Knoten gemeinsam genutzt wird? Was ist die Auswirkung auf Leistungen und Skalierbarkeit?

Hat jemand eine bessere Modellierungslösung?

+1

Es würde helfen, ein bisschen mehr über die Metadaten zu wissen. Hat jeder Benutzer eigene Metadaten zu einem Film oder ist er nicht benutzerspezifisch? Gibt es einen Grund, warum Sie die Metadaten nicht als Eigenschaften auf den Filmknoten speichern können? Sind einige Teile von Metadaten dazu gedacht, sich wie Tags zu verhalten (was bedeutet, dass Sie von Metadaten zu Filmen abfragen können)? Oder greifen Sie jemals nur auf Metadaten eines Films und nicht direkt zu? – InverseFalcon

+0

Nein, Metadaten sind nicht benutzerspezifisch. Aber sie sind lokalisiert (ich habe das zur Vereinfachung nicht erwähnt). Ich denke, die einzige Möglichkeit, Metadaten auf Filmknoten zu speichern, ist innerhalb von Arrays, oder? Aber dies wäre nicht effizient für Abfragen Abfragen. Wir müssen Filme basierend auf ihren Metadaten filtern können. Und ja, wir greifen immer auf Metadaten von einem Film zu. – tigrou83

+0

Ich bin nicht genau sicher, was Sie meinen, indem Sie nur Metadaten in Arrays speichern können. Gibt es einen Grund, warum Sie nicht einfach Eigenschaften für Ihre Filmknoten festlegen können? Sie können immer nach Knoteneigenschaften innerhalb Ihrer WHERE-Klauseln filtern. Ich bin immer noch neugierig, welche Art von Metadaten das sein soll ... was unterscheidet es von den Knoteneigenschaften, die Sie verwenden wollten? Können Sie einige Beispiele für diese Metadaten angeben? – InverseFalcon

Antwort

3

tl, dr: Gehen Sie mit Ansatz A. Sie mit verwaisten :Locale Knoten außer für die regelmäßige Bereinigung nicht stören, werden sie keine Auswirkungen auf die Abfrageleistung.

Ihr Ansatz 'A' ist bei weitem die bessere Lösung. Sie müssen diese Daten vom :Movie-Knoten entfernen, Sie haben Recht, weil es entweder eine verschachtelte Map oder eine Liste von Maps sein muss, von denen keine von den Node-Eigenschaften unterstützt wird. Für die Speicherung könnten Sie diese in eine Liste von Listen konvertieren, aber das wird sehr schwierig abzufragen sein, noch weniger schnell abfragen. Ihre Sorge über "verwaiste" Knoten ist unerheblich; Es wird die Abfrageleistung und die Datengröße trivial beeinflussen, wenn überhaupt, und es ist unglaublich einfach, es in regelmäßigen Abständen zu bereinigen, um Ihre Gedanken auf jeden Fall zu erleichtern.

MATCH (x:Locale) WHERE NOT (x) <- [:METADATA] -() DETACH DELETE x 

Sie, dass einmal im Monat oder nie, es wird wirklich nicht, dass Sie viel beeinflussen. Ihre Abfrage ist bereits durch den Rest des Pfads eingeschränkt. Wenn Sie also verwaiste Knoten nicht wesentlich anhängen, fügen Sie nur einen kleinen Prozentsatz zu dem wahrscheinlich größten Satz in Ihrer Abfrage hinzu, der ebenfalls gelöscht wird durch Abfrageoperation beim ersten Durchlauf.

Wie beim Sperren betrifft dies nur Schreibanforderungen, und zwar nur dann, wenn eine Schreibtransaktion geöffnet ist. Sie können eine Million schreibgeschützte Abfragen ausführen, während der Schreibvorgang läuft und nichts davon betroffen ist. Trotzdem ist das zweite Modell anfällig für eine verlangsamte Abfrageleistung, da Sie, wie oben erwähnt, keine Indizes auf Beziehungseigenschaften setzen können.

1

Sie können nur speichern die „Metadaten“ direkt als Eigenschaften jeden Movie Knoten (ohne zu key und value zurückgreifen). Dies ist der einfachste Ansatz, der Sperrprobleme vermeidet und die Anzahl der erforderlichen Knoten und Beziehungen minimiert. Sie können zu einem Knoten jederzeit weitere Eigenschaften hinzufügen. Mit diesem Ansatz können Sie auch Indizes für bestimmte Movie Eigenschaften hinzufügen, auf die Sie beim Starten Ihrer Abfragen schnell zugreifen müssen.

Zum Beispiel:

CREATE (m:Movie {id: 123, title: 'Men in black', director: 'Barry Sonnenfeld'}); 

[UPDATE]

Wenn Sie Ihre „Metadaten“ sauber getrennt halten müssen von Ihren „Daten“ und Sie müssen auch die Metadaten lokalisieren können (einschließlich die Spezifikation einer locale Eigenschaft), dann können Sie jeden Knoten Movie mit einem einzelnen Knoten Metadata für jedes Gebietsschema verknüpfen. Ein Metadata Knoten direkt enthält alle Metadaten-Eigenschaften für ein einzelnes Gebietsschema für einen bestimmten Movie Knoten.

Cypher kann verwendet werden, um "kaskadierende Löschungen" durchzuführen. Zum Beispiel:

MATCH (m:Movie {id: 123}) 
OPTIONAL MATCH p=(m)-->() 
DELETE p; 
+0

Es ist ein einfacher Ansatz, du hast Recht. Aber ich muss Metadaten von anderen Attributen unterscheiden, weil sie Geschäftsinformationen getrennt von den anderen technischen Attributen sind. Und ich habe auch einen wichtigen Teil vergessen (zu viel Vereinfachung tut mir leid), Metadaten haben auch eine "locale" -Eigenschaft (zum Gruppieren von Metadaten pro Sprache). Tut mir leid, ich hätte es vorher sagen sollen, es ändert alles. Ich werde den ersten Beitrag mit diesen Details aktualisieren. – tigrou83

+0

Ich habe meine Antwort aktualisiert. – cybersam

+0

Ja genau, also wird es ähnlich wie Lösung A aussehen (außer dass wir keinen Knoten pro Metadaten haben werden). Diese Lösung funktioniert, aber der Nachteil besteht zum Beispiel darin, Kaskadenlöschungen manuell zu verwalten (was von der von mir verwendeten Quelle spring-data-neo4j nicht unterstützt wird). Ich hatte gehofft, eine Lösung zu finden, wo ich das vermeiden kann. – tigrou83

Verwandte Themen