Domanda

Puoi condividere i tuoi pensieri come si dovrebbe implementare i dati di versioning in MongoDB. (Ho chiesto quanto riguarda Cassandra . Se avete qualche pensieri che dB è migliore di quella condivisione per favore)

Supponiamo che ho bisogno di record di versione in una semplice rubrica. (Record rubrica vengono memorizzate come oggetti JSON piatti). Mi aspetto che la storia:

  • sarà usata raramente
  • sarà utilizzato in una sola volta per presentare in maniera "macchina del tempo"
  • non ci saranno più versioni di poche centinaia a un singolo record. La storia non scadrà.

sto considerando i seguenti approcci:

  • Creare una nuova collezione di oggetti per la storia vendite di registrazioni o modifiche ai record. Sarebbe memorizzare un oggetto per la versione con un riferimento alla voce della rubrica. Tali registrazioni avrebbe appare come segue:

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

    Questo approccio può essere modificato per memorizzare una serie di versioni per documento. Ma questo sembra essere approccio più lento, senza alcun vantaggio.

  • versioni deposito come serializzato (JSON) oggetto attaccato alle voci della rubrica. Non sono sicuro di come collegare tali oggetti ai documenti MongoDB. Forse come un array di stringhe. ( Modellato semplice documento delle versioni con CouchDB )

È stato utile?

Soluzione

La prima grande questione durante le immersioni per questo è "Come ti desidera memorizzare gruppi di modifiche"

  1. Diffs?
  2. copie intero disco?

Il mio personale approccio sarebbe quello di memorizzare diff. Poiché la visualizzazione di questi diff è in realtà un'azione speciale, vorrei mettere le diff in un diverso collezione "storia".

I userebbe la collezione diverso per risparmiare spazio di memoria. In genere non si desidera una storia completa per una semplice query. Quindi, mantenere la storia fuori l'oggetto si può anche tenerlo fuori della memoria comunemente si accede quando i dati viene eseguita una query.

Per rendere la vita facile, vorrei fare un documento di storia contiene un dizionario di diff data e ora. Qualcosa di simile a questo:

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

Per rendere la mia vita molto facile, mi farebbe questa parte del mio DataObjects (EntityWrapper, a prescindere) che uso per accedere ai miei dati. Generalmente questi oggetti hanno una qualche forma di storia, così che si può facilmente sovrascrivere il metodo save() a fare questo cambiamento, allo stesso tempo.

UPDATE: 2015-10

Sembra che v'è ora una specifica per la gestione di JSON diff . Questo mi sembra un modo più robusto per memorizzare i diff / modifiche.

Altri suggerimenti

V'è un sistema di controllo delle versioni chiamato "Vermongo", che gli indirizzi alcuni aspetti che non sono stati trattati nelle altre risposte.

Uno di questi problemi è aggiornamenti simultanei, un altro è l'eliminazione di documenti.

Vermongo memorizza copie complete dei documenti in una raccolta ombra. Per alcuni casi d'uso che questo potrebbe causare troppo in alto, ma penso che semplifica molte cose.

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

Ecco un'altra soluzione con un unico documento per la versione corrente e tutte le vecchie versioni:

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

data contiene tutti le versioni. L'array data è ordine , le nuove versioni avranno $pushed solo alla fine della matrice. data.vid è l'id versione, che è un numero incrementale.

Scarica la versione più recente:

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

Ottieni una versione specifica per vid:

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

Return campi solo specificati:

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

Inserisci nuova versione: (e prevenire inserto concomitante / update)

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

2 è la vid della corrente versione più recente ed 3 è la nuova versione sempre inserito. Perché è necessario il più recente vid di versione, è facile fare ottenere la prossima versione del vid:. nextVID = oldVID + 1

La condizione $and assicurerà, che 2 è l'ultima vid.

In questo modo non c'è bisogno di un indice univoco, ma la logica dell'applicazione deve prendersi cura di incrementare il vid su inserto.

Rimuovi una versione specifica:

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

Questo è tutto!

(ricordate il limite di 16 MB per ogni documento)

Se siete alla ricerca di una soluzione pronta-to-roll -

Mongoid ha costruito in semplice delle versioni

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

mongoid-storia è un plugin di Ruby che fornisce una soluzione notevolmente più complessa con l'auditing, Annulla e Ripristina

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

Ho lavorato attraverso questa soluzione che ospita una pubblicazione, bozza e versioni storiche dei dati:

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

I spiegare il modello più qui: http: //software.danielwatrous. com / che rappresenta-revisione-data-in-mongodb /

Per coloro che possono implementare qualcosa di simile in Java , ecco un esempio:

http://software.danielwatrous.com/using -java-to-lavoro-con-di versione-dati /

Tra cui tutto il codice che si può sborsare, se vi piace

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

Se si utilizza mangusta, ho trovato il seguente plugin per essere un utile implementazione del formato JSON Patch

mangusta-patch-storia

Un'altra opzione è quella di utilizzare mangusta-storia 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.

Ho usato il seguito pacchetto per un progetto di meteore / MongoDB, e funziona bene, il vantaggio principale è che memorizza la storia / revisioni all'interno di un array nello stesso documento, quindi senza necessità di ulteriori pubblicazioni o middleware di accesso cambiare la storia. E 'in grado di supportare un numero limitato di versioni precedenti (es. Versioni scorso dieci), supporta anche il cambiamento-concatenazione (in modo che tutti i cambiamenti avvenuti in un periodo prestabilito saranno coperti da una revisione).

nicklozon / meteora-raccolta-revisioni

Un'altra opzione è quella di utilizzare il suono Meteor Vermongo ( qui )

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top