Frage

Können Sie Ihre Meinung, wie Sie Daten Versionierung in MongoDB implementieren würde. (Ich habe ähnliche Frage in Bezug auf Cassandra gefragt. Wenn Sie irgendwelche Gedanken, die für diesen bitte Aktie db besser ist)

Nehmen wir an, dass ich in einem einfachen Adressbuch Version Aufzeichnungen müssen. (Adressbuch Aufzeichnungen sind als flache json Objekte gespeichert). Ich erwarte, dass die Geschichte:

  • wird selten verwendet werden
  • werden alle an verwendet werden, wenn es in einer „Zeitmaschine“ Art und Weise zu präsentieren
  • wird es nicht mehr Versionen als einige hundert zu einem einzigen Datensatz. Geschichte wird nicht ab.

Ich betrachte die folgenden Ansätze:

  • Erstellen Sie eine neue Objektsammlung zu speichern Geschichte der Aufzeichnungen oder Änderungen an den Datensätzen. Es wäre speichern ein Objekt pro Version mit einem Verweis auf die Adressbucheintrag. Diese Aufzeichnungen würde sieht wie folgt aus:

    {
     '_id': 'new id',
     'user': user_id,
     'timestamp': timestamp,
     'address_book_id': 'id of the address book record' 
     'old_record': {'first_name': 'Jon', 'last_name':'Doe' ...}
    }
    

    Dieser Ansatz kann modifiziert werden, um eine Reihe von Versionen pro Dokument zu speichern. Aber dies scheint ohne Vorteile langsamer Ansatz.

  • Shop-Versionen als serialisiert (JSON) Objekt an Adressbucheinträge. Ich bin mir nicht sicher, wie solche Objekte zu MongoDB Dokumenten zu befestigen. Vielleicht als ein Array von Strings. ( Modelliert nach einem einfachen Dokument Versioning mit CouchDB )

War es hilfreich?

Lösung

Die erste große Frage beim Tauchen in zu diesem ist „wie wollen Sie speichern Changesets“

  1. Diffs?
  2. Ganze Rekord Kopien?

Mein persönlicher Ansatz zum Speichern von diffs wäre. Da die Anzeige dieser Differentiale ist wirklich eine besondere Aktion, würde ich die Diffs in einer anderen „Geschichte“ Sammlung setzen.

würde ich die andere Sammlung verwenden, um Speicherplatz einzusparen. Sie wollen in der Regel keine vollständige Geschichte für eine einfache Abfrage. So durch die Geschichte aus dem Objekt zu halten, kann man es auch hält aus den häufig zugegriffen Speichern, wenn diese Daten abgefragt wird.

mein Leben einfach zu machen, würde ich eine Geschichte Dokument ein Wörterbuch der zeitgestempelt diffs enthalten machen. So etwas wie folgt aus:

{
    _id : "id of address book record",
    changes : { 
                1234567 : { "city" : "Omaha", "state" : "Nebraska" },
                1234568 : { "city" : "Kansas City", "state" : "Missouri" }
               }
}

Um mein Leben einfach zu machen, würde ich diesen Teil meiner Datenobjekte (EntityWrapper, was auch immer), dass ich meine Daten verwenden, um zuzugreifen. Im Allgemeinen haben diese Objekte eine gewisse Form der Geschichte, so dass Sie bequem die save() Methode außer Kraft setzen kann, um diese Änderung vorzunehmen zugleich.

UPDATE: 2015-10

Es sieht aus wie es jetzt ist eine Spezifikation für JSON Umgang diffs . Dies scheint eine robustere Art und Weise die diffs / Änderungen zu speichern.

Andere Tipps

Es ist ein Versionsschema namens „Vermongo“, die Adressen einige Aspekte, die mit nicht in den anderen Antworten behandelt haben.

Eines dieser Probleme gleichzeitige Aktualisierungen sind, eine andere ist es, Dokumente zu löschen.

Vermongo speichert vollständige Dokumentkopien in einem Schatten Sammlung. Bei einigen Anwendungsfällen kann dies zu viel Aufwand verursachen, aber ich denke, es vereinfacht auch viele Dinge.

https://github.com/thiloplanz/v7files/wiki/Vermongo

Hier ist eine andere Lösung ein einzelnes Dokument für die aktuelle Version und alle alten Versionen mit:

{
    _id: ObjectId("..."),
    data: [
        { vid: 1, content: "foo" },
        { vid: 2, content: "bar" }
    ]
}

data enthält alle Versionen. Die data Array ist bestellt , neue Versionen werden nur bis zum Ende des Arrays $pushed erhalten. data.vid ist die Version-ID, die eine fortlaufende Nummer.

Erhalten Sie die aktuellste Version:

find(
    { "_id":ObjectId("...") },
    { "data":{ $slice:-1 } }
)

eine bestimmte Version von vid Erhalten Sie:

find(
    { "_id":ObjectId("...") },
    { "data":{ $elemMatch:{ "vid":1 } } }
)

Zurück nur bestimmte Felder:

find(
    { "_id":ObjectId("...") },
    { "data":{ $elemMatch:{ "vid":1 } }, "data.content":1 }
)

Legen Sie eine neue Version: (und verhindern gleichzeitig insert / update)

update(
    {
        "_id":ObjectId("..."),
        $and:[
            { "data.vid":{ $not:{ $gt:2 } } },
            { "data.vid":2 }
        ]
    },
    { $push:{ "data":{ "vid":3, "content":"baz" } } }
)

2 ist die vid der aktuellen neuesten Version und 3 ist die neue Version eingefügt zu werden. Weil Sie die aktuellste Version der vid benötigen, ist es einfach, die nächste Version des vid zu tun bekommen. nextVID = oldVID + 1

Die $and Bedingung wird sichergestellt, dass 2 ist die neueste vid.

Auf diese Weise gibt es keine Notwendigkeit für einen eindeutigen Index, aber die Anwendungslogik hat von Erhöhen des vid auf dem Einsatz zu nehmen.

eine bestimmte Version entfernen:

update(
    { "_id":ObjectId("...") },
    { $pull:{ "data":{ "vid":2 } } }
)

Das ist es!

(erinnere mich an die 16 MB pro Dokument Grenze)

Wenn Sie sich für eine ready-to-Roll-Lösung suchen -

Mongoid hat in einfacher Versionierung gebaut

http://mongoid.org/en/mongoid/docs/extras. html # Versionierung

mongoid-Geschichte ist eine Ruby-Plugin, das eine wesentlich kompliziertere Lösung mit der Prüfung bietet, Undo und Redo

https://github.com/aq1018/mongoid-history

Ich arbeitete durch diese Lösung, die einen veröffentlichten, Entwurf und historische Versionen der Daten bietet Platz:

{
  published: {},
  draft: {},
  history: {
    "1" : {
      metadata: <value>,
      document: {}
    },
    ...
  }
}

Ich erkläre das Modell weiter hier: http: //software.danielwatrous. com / repräsentiere-Revision-data-in-mongodb /

Für diejenigen, die so etwas wie dies in Java , hier ist ein Beispiel implementieren können:

http://software.danielwatrous.com/using -java-to-Work-mit-versioniert-data /

einschließlich aller Code dass Sie berappen, wenn Sie wie

https://github.com/dwatrous/mongodb-revision-objects

Wenn Sie Mungo verwenden, habe ich das folgende Plugin gefunden eine nützliche Implementierung des JSON-Patch Format zu sein

Mungo-patch-Geschichte

Eine weitere Möglichkeit ist die Verwendung Mungo-Geschichte Plugin.

let mongoose = require('mongoose');
let mongooseHistory = require('mongoose-history');
let Schema = mongoose.Schema;

let MySchema = Post = new Schema({
    title: String,
    status: Boolean
});

MySchema.plugin(mongooseHistory);
// The plugin will automatically create a new collection with the schema name + "_history".
// In this case, collection with name "my_schema_history" will be created.

Ich habe die unten Paket für ein Meteor / MongoDB-Projekt verwendet, und es funktioniert gut, ist der Hauptvorteil, dass es speichert Geschichte / Revisionen innerhalb eines Arrays in demselben Dokument, daher keine Notwendigkeit für weitere Publikationen oder Middleware für den Zugriff Geschichte verändern. Es kann eine begrenzte Anzahl von früheren Versionen unterstützen (ex. Letzten zehn Versionen), sondern unterstützt auch Wechsel Verkettung (so alle Änderungen innerhalb eines bestimmten Zeitraums geschehen ist, wird durch eine Revision abgedeckt werden).

nicklozon / Meteor sammel Überarbeitungen

Eine weitere Sound-Option ist Meteor Vermongo ( hier )

zu verwenden,
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top