Pregunta

¿Puede compartir sus pensamientos ¿cómo poner en práctica los datos de versiones en MongoDB. (He pedido Cassandra . Si tiene alguna pensamientos que dB es mejor para esa acción por favor)

Supongamos que necesito registros de versión en una libreta de direcciones simple. (Registros de libreta de direcciones se almacenan como objetos JSON planas). Espero que la historia:

  • se utiliza con poca frecuencia
  • será utilizado a la vez para presentarlo de una manera "máquina del tiempo"
  • no habrá más versiones que unos pocos cientos a un único registro. la historia no expirará.

Estoy considerando los siguientes enfoques:

  • Crear una nueva colección de objetos para almacenar el historial de registros o cambios en los registros. Sería almacenar un objeto por la versión con una referencia a la entrada de la libreta de direcciones. Tales antecedentes se ve de la siguiente manera:

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

    Este enfoque puede ser modificado para almacenar una serie de versiones por documento. Pero esto parece ser el enfoque más lento y sin ninguna ventaja.

  • Las versiones Store como objeto serializado (JSON) unido a las entradas de la libreta de direcciones. No estoy seguro de cómo colocar estos objetos a los documentos MongoDB. Tal vez como una matriz de cadenas. ( Siguiendo el modelo de simple versiones de documentos con CouchDB )

¿Fue útil?

Solución

La primera gran pregunta cuando se bucea en que esto es "¿Cómo se quieren almacenar conjuntos de cambios"

  1. Diffs?
  2. graban todo copias?

Mi enfoque personal sería diferenciaciones de las tiendas. Debido a que el despliegue de estas diferenciaciones es realmente una acción especial, me puse los diferenciales en una colección de "historia" diferente.

Yo usaría la colección diferente para ahorrar espacio en la memoria. En general, usted no quiere un historial completo para una simple consulta. Por lo tanto, manteniendo la historia del objeto también puede mantenerlo fuera de la memoria comúnmente visitada cuando se consulta los datos.

Para hacer mi vida más fácil, me gustaría hacer un documento de la historia contiene un diccionario de diferenciaciones con fecha y hora. Algo como esto:

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

Para hacer mi vida muy fácil, lo haría esta parte de mis DataObjects (EntityWrapper, lo que sea) que utilizo para acceder a mis datos. En general, estos objetos tienen algún tipo de historia, de manera que se puede reemplazar fácilmente el método save() para realizar este cambio, al mismo tiempo.

UPDATE: 2015-10

Parece que ahora hay una especificación para el manejo de JSON diffs . Esta parece ser una manera más robusta para almacenar los diferenciales / cambios.

Otros consejos

Hay un esquema de versiones llamado "Vermongo", que trata algunos aspectos que no han sido tratados en las otras respuestas.

Uno de estos problemas es actualizaciones simultáneas, otra es la eliminación de documentos.

Vermongo almacena las copias de documentos completos en una colección sombra. Para algunos casos de uso que esto podría causar demasiada sobrecarga, pero creo que también simplifica muchas cosas.

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

Aquí hay otra solución utilizando un único documento para la versión actual y todas las versiones anteriores:

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

data contiene todos los versiones. La matriz data es ordenado , nuevas versiones sólo se les $pushed al final de la matriz. data.vid es el identificador de versión, que es un número incremental.

Obtener la versión más reciente:

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

Obtener una versión específica por vid:

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

Vuelta campos sólo se especifica:

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

Insertar nueva versión: (y evitar inserciones concurrentes / actualización)

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

2 es la vid de la versión más reciente y actual 3 es la nueva versión para insertarse. Porque se necesita la última versión de vid, es fácil de hacer llegar la próxima versión de vid:. nextVID = oldVID + 1

La condición $and asegurará, que es la última 2 vid.

De esta manera no hay necesidad de un índice único, pero la lógica de la aplicación tiene que cuidar de incrementar la vid en el inserto.

Eliminar una versión específica:

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

Eso es todo!

(recuerde que el límite de 16 MB por cada documento)

Si usted está buscando una solución lista para-roll -

Mongoid ha construido en el sencillo control de versiones

http://mongoid.org/en/mongoid/docs/extras. html # de versiones

MongoId-historia es un plugin para Ruby que proporciona una solución mucho más complicado con la auditoría, deshacer y rehacer

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

Yo trabajaba a través de esta solución que se adapta a una publicación, borrador y las versiones antiguas de los datos:

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

Me explicar el modelo más aquí: http: //software.danielwatrous. com / representando-revisión-Data-en-mongodb /

Para aquellos que pueden poner en práctica algo como esto en Java , he aquí un ejemplo:

http://software.danielwatrous.com/using -java al trabajo-con-versionado-datos /

La inclusión de todo el código que se puede bifurcar, si te gusta

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

Si está utilizando mangosta, he encontrado el siguiente plugin para ser una aplicación útil del formato de JSON Patch

mangosta-patch-historia

Otra opción es usar mangosta-historia plug-in.

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.

He utilizado el siguiente paquete para un proyecto de meteoros / MongoDB, y funciona bien, la principal ventaja es que almacena la historia / revisiones dentro de una matriz en el mismo documento, por lo tanto, hay necesidad de un publicaciones adicionales o middleware para el acceso cambia la historia. Se puede admitir un número limitado de versiones anteriores (ej. Las versiones pasado diez), que también es compatible con el cambio-de concatenación (por lo que todos los cambios ocurridos dentro de un período específico será cubierto por una revisión).

nicklozon / meteoro-collection-revisiones

Otra opción es utilizar sonido Meteor Vermongo ( aquí )

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top