Können Sie uns Ihre Gedanken mitteilen, wie Sie die Datenversionierung in MongoDB implementieren würden? (Ich habe eine ähnliche Frage zu Cassandra gestellt . Wenn Sie irgendwelche Gedanken haben, welche Datenbank dafür besser ist, teilen Sie sie bitte mit.)
Angenommen, ich muss Datensätze in einem einfachen Adressbuch versionieren. (Adressbuchdatensätze werden als flache JSON-Objekte gespeichert). Ich erwarte, dass die Geschichte:
- wird selten verwendet
- wird auf einmal verwendet, um es in einer "Zeitmaschinen" -Mode zu präsentieren
- Es wird nicht mehr als ein paar hundert Versionen für einen einzelnen Datensatz geben. Die Geschichte läuft nicht ab.
Ich denke über folgende Ansätze nach:
Erstellen Sie eine neue Objektsammlung, um den Verlauf von Datensätzen oder Änderungen an den Datensätzen zu speichern. Es würde ein Objekt pro Version mit einem Verweis auf den Adressbucheintrag speichern. Solche Aufzeichnungen würden wie folgt aussehen:
{ '_id': 'neue ID', 'Benutzer': Benutzer_ID, 'Zeitstempel': Zeitstempel, 'address_book_id': 'ID des Adressbuchdatensatzes' 'old_record': {'first_name': 'Jon', 'last_name': 'Doe' ...} }}
Dieser Ansatz kann geändert werden, um ein Array von Versionen pro Dokument zu speichern. Dies scheint jedoch ein langsamerer Ansatz ohne Vorteile zu sein.
Speichern Sie Versionen als serialisiertes (JSON) Objekt, das an Adressbucheinträge angehängt ist. Ich bin nicht sicher, wie ich solche Objekte an MongoDB-Dokumente anhängen soll. Vielleicht als eine Reihe von Zeichenfolgen. ( Modelliert nach der einfachen Dokumentversionierung mit CouchDB )
quelle
Antworten:
Die erste große Frage beim Tauchen in dafür ist „wie wollen Sie speichern Changesets “ ?
Mein persönlicher Ansatz wäre es, Unterschiede zu speichern. Da die Anzeige dieser Unterschiede wirklich eine besondere Aktion ist, würde ich die Unterschiede in eine andere "Geschichts" -Sammlung einfügen.
Ich würde die andere Sammlung verwenden, um Speicherplatz zu sparen. Sie möchten im Allgemeinen keinen vollständigen Verlauf für eine einfache Abfrage. Wenn Sie also den Verlauf aus dem Objekt heraushalten, können Sie ihn auch aus dem Speicher heraushalten, auf den häufig zugegriffen wird, wenn diese Daten abgefragt werden.
Um mir das Leben zu erleichtern, würde ich ein Verlaufsdokument erstellen, das ein Wörterbuch mit zeitgestempelten Unterschieden enthält. Etwas wie das:
Um mir das Leben wirklich zu erleichtern, würde ich diesen Teil meiner DataObjects (EntityWrapper, was auch immer) für den Zugriff auf meine Daten verwenden. Im Allgemeinen haben diese Objekte eine Form des Verlaufs, sodass Sie die
save()
Methode leicht überschreiben können , um diese Änderung gleichzeitig vorzunehmen.UPDATE: 2015-10
Es sieht so aus, als gäbe es jetzt eine Spezifikation für den Umgang mit JSON-Unterschieden . Dies scheint eine robustere Methode zum Speichern der Unterschiede zu sein.
quelle
changes
ist wirklich einfach:db.hist.update({_id: ID}, {$set { changes.12345 : CHANGES } }, true)
Dadurch wird ein Upsert ausgeführt, bei dem nur die erforderlichen Daten geändert werden. Mongo erstellt Dokumente mit "Pufferplatz", um diese Art von Änderung zu handhaben. Außerdem wird überwacht, wie sich Dokumente in einer Sammlung ändern, und die Puffergröße für jede Sammlung wird geändert. MongoDB ist also genau für diese Art von Änderung ausgelegt (neue Eigenschaft hinzufügen / zum Array verschieben).Es gibt ein Versionsschema namens "Vermongo", das einige Aspekte behandelt, die in den anderen Antworten nicht behandelt wurden.
Eines dieser Probleme sind gleichzeitige Aktualisierungen, ein anderes das Löschen von Dokumenten.
Vermongo speichert vollständige Dokumentkopien in einer Schattensammlung. In einigen Anwendungsfällen kann dies zu viel Overhead verursachen, aber ich denke, es vereinfacht auch viele Dinge.
https://github.com/thiloplanz/v7files/wiki/Vermongo
quelle
Hier ist eine weitere Lösung, bei der ein einziges Dokument für die aktuelle Version und alle alten Versionen verwendet wird:
data
enthält alle Versionen. Dasdata
Array ist bestellt , neue Versionen werden nur$push
bis zum Ende des Arrays bearbeitet.data.vid
ist die Versions-ID, bei der es sich um eine inkrementelle Zahl handelt.Holen Sie sich die neueste Version:
Holen Sie sich eine bestimmte Version von
vid
:Geben Sie nur die angegebenen Felder zurück:
Neue Version einfügen : (und gleichzeitiges Einfügen / Aktualisieren verhindern)
2
ist dievid
aktuellste Version und3
wird die neue Version eingefügt. Da Sie die neuesten Versionen benötigenvid
, ist es einfach, die nächsten Versionen zu erhaltenvid
:nextVID = oldVID + 1
.Die
$and
Bedingung wird sicherstellen, dass dies2
die neueste istvid
.Auf diese Weise ist kein eindeutiger Index erforderlich, aber die Anwendungslogik muss dafür sorgen, dass die
vid
Einfügung erhöht wird .Entfernen Sie eine bestimmte Version:
Das ist es!
(Beachten Sie das Limit von 16 MB pro Dokument.)
quelle
Wenn Sie nach einer gebrauchsfertigen Lösung suchen -
Mongoid hat eine einfache Versionierung eingebaut
http://mongoid.org/en/mongoid/docs/extras.html#versioning
mongoid-history ist ein Ruby-Plugin, das eine wesentlich kompliziertere Lösung mit Auditing, Undo und Redo bietet
https://github.com/aq1018/mongoid-history
quelle
Ich habe diese Lösung durchgearbeitet, die eine veröffentlichte, Entwurfs- und historische Version der Daten enthält:
Ich erkläre das Modell hier weiter: http://software.danielwatrous.com/representing-revision-data-in-mongodb/
Für diejenigen, die so etwas in Java implementieren können , hier ein Beispiel:
http://software.danielwatrous.com/using-java-to-work-with-versioned-data/
Einschließlich des gesamten Codes, den Sie bei Bedarf teilen können
https://github.com/dwatrous/mongodb-revision-objects
quelle
Wenn Sie Mungo verwenden, habe ich festgestellt, dass das folgende Plugin eine nützliche Implementierung des JSON-Patch- Formats ist
Mungo-Patch-Geschichte
quelle
Eine andere Möglichkeit ist die Verwendung des Mungo-Verlaufs- Plugins.
quelle
Ich habe das folgende Paket für ein Meteor / MongoDB-Projekt verwendet und es funktioniert gut. Der Hauptvorteil besteht darin, dass der Verlauf / die Revisionen in einem Array im selben Dokument gespeichert werden, sodass keine zusätzlichen Veröffentlichungen oder Middleware für den Zugriff auf den Änderungsverlauf erforderlich sind . Es kann eine begrenzte Anzahl früherer Versionen unterstützen (z. B. die letzten zehn Versionen), es unterstützt auch die Verkettung von Änderungen (sodass alle Änderungen, die innerhalb eines bestimmten Zeitraums vorgenommen wurden, von einer Revision abgedeckt werden).
Nicklozon / Meteor-Sammlung-Revisionen
Eine weitere Soundoption ist die Verwendung von Meteor Vermongo ( hier ).
quelle