Question

Pouvez-vous partager vos pensées comment voulez-vous mettre en œuvre des données dans MongoDB versioning. (Je l'ai demandé question similaire au sujet Cassandra. Si vous avez des pensées qui db est mieux pour cette action) s'il vous plaît

Supposons que je dois des documents de version dans un carnet d'adresses simple. (Dossiers de carnet d'adresses sont stockées sous forme d'objets plats JSON). Je pense que l'histoire:

  • sera rarement utilisé
  • sera utilisé à la fois pour le présenter de façon « time machine »
  • il n'y aura pas plus de versions que quelques centaines à un seul enregistrement. l'histoire n'expirera.

J'envisage les approches suivantes:

  • Créer une nouvelle collection d'objets à l'histoire de stocker des enregistrements ou des modifications aux dossiers. Il stockerait un objet par version avec une référence à l'entrée du carnet d'adresses. Ces dossiers seraient se présente comme suit:

    {
     '_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' ...}
    }
    

    Cette approche peut être modifiée pour stocker un tableau de versions par document. Mais cela semble être plus lente approche sans avantages.

  • versions en magasin comme objet sérialisé (JSON) attaché à l'adresse dans l'annuaire. Je ne sais pas comment attacher ces objets aux documents MongoDB. Peut-être comme un tableau de chaînes. ( Modelé simple document avec Versioning CouchDB)

Était-ce utile?

La solution

La première grande question lors de la plongée dans c'est « comment voulez-vous stocker changesets »

  1. Diffs?
  2. copies record entier?

Mon approche personnelle serait de diffs magasin. Parce que l'affichage de ces diffs est vraiment une action spéciale, je mettrais les diffs dans une autre collection « historique ».

J'utiliser la collection différente pour économiser l'espace mémoire. Vous ne voulez pas généralement un historique complet pour une requête simple. Donc, en gardant l'histoire de l'objet que vous pouvez le garder hors de la mémoire fréquemment consultées lorsque ces données est interrogé.

Pour rendre ma vie facile, je voudrais faire un document d'histoire contient un dictionnaire de diffs horodatés. Quelque chose comme ceci:

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

Pour ma vie vraiment facile, je ferais cette partie de mes DataObjects (EntityWrapper, peu importe) que j'utiliser pour accéder à mes données. En général, ces objets ont une certaine forme d'histoire, de sorte que vous pouvez facilement remplacer la méthode save() pour faire ce changement en même temps.

Mise à jour: 2015-10

On dirait qu'il est maintenant une spécification pour la manipulation JSON diffs . Cela semble être une façon plus robuste pour stocker les diffs / modifications.

Autres conseils

Il existe un système appelé versioning « Vermongo » qui traite de certains aspects qui ne sont pas traités dans les autres réponses.

L'un de ces problèmes est mises à jour simultanées, un autre est la suppression des documents.

Vermongo stocke des copies complètes de documents dans une collection d'ombre. Pour certains cas d'utilisation cela pourrait causer trop de frais généraux, mais je pense que cela simplifie aussi beaucoup de choses.

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

Voici une autre solution en utilisant un seul document pour la version actuelle et toutes les anciennes versions:

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

data contient toutes les versions . Le tableau de data est ordonné , de nouvelles versions ne se $pushed à la fin du tableau. data.vid est l'identifiant de version, qui est un nombre incrémenter.

Obtenir la version la plus récente:

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

Obtenir une version spécifique vid:

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

Afficher uniquement les champs spécifiés:

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

Insérer une nouvelle version: (et empêcher insertion / mise à jour simultanée)

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

2 est le vid de la version actuelle la plus récente et 3 est la nouvelle version s'insérée. Parce que vous avez besoin de vid version la plus récente, il est facile de faire se vid de la prochaine version. nextVID = oldVID + 1

La condition de $and veillera à ce que 2 est le dernier vid.

De cette façon, il n'y a pas besoin d'un index unique, mais la logique d'application doit prendre soin de incrémenter la vid sur insert.

Supprimer une version spécifique:

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

Ca y est!

(rappelez-vous le 16MB par limite de document)

Si vous êtes à la recherche d'une solution prête à rouler -

MongoId a construit dans le versioning simple,

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

MongoId-histoire est un plug-in Ruby qui fournit une solution beaucoup plus compliquée avec l'audit, défont et refont

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

J'ai travaillé dans cette solution qui accueille une publication, le projet et les versions historiques des données:

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

J'explique le modèle plus ici: http: //software.danielwatrous. com / représentant la révision-Data-in-mongodb /

Pour ceux qui peuvent mettre en œuvre quelque chose comme ceci Java , voici un exemple:

http://software.danielwatrous.com/using -java au travail avec versionné-data /

Y compris tout le code que vous pouvez fourchette, si vous aimez

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

Si vous utilisez mangouste, j'ai trouvé le plugin suivante pour une mise en œuvre utile du JSON Patch Format

mangouste-patch-histoire

Une autre option consiste à utiliser mangouste-histoire 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.

Je l'ai utilisé le ci-dessous package pour un projet de météores / MongoDB, et il fonctionne bien, le principal avantage est qu'il stocke l'histoire / révisions dans un tableau dans le même document, donc pas besoin d'une publications supplémentaires ou middleware d'accès changement historique. Il peut prendre en charge un nombre limité de versions antérieures (ex. Dernières versions de dix), il prend également en charge le changement concaténation (donc tous les changements ont eu lieu dans un délai spécifique sera couvert par une révision).

nicklozon / météore-collection-révisions

Une autre option est d'utiliser son Meteor Vermongo ( )

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top