¿Puede compartir sus pensamientos sobre cómo implementaría el control de versiones de datos en MongoDB? (He hecho una pregunta similar con respecto a Cassandra . Si tiene alguna idea sobre qué base de datos es mejor para eso, por favor comparta)
Supongamos que necesito versionar registros en una libreta de direcciones simple. (Los registros de la libreta de direcciones se almacenan como objetos planos json). Espero que la historia:
- se usará con poca frecuencia
- se utilizará de una vez para presentarlo en forma de "máquina del tiempo"
- no habrá más versiones que unos pocos cientos para un solo registro. La historia no caducará.
Estoy considerando los siguientes enfoques:
Cree una nueva colección de objetos para almacenar el historial de registros o los cambios en los registros. Almacenaría un objeto por versión con una referencia a la entrada de la libreta de direcciones. Dichos registros se verían de la siguiente manera:
{ '_id': 'nueva identificación', 'user': user_id, 'marca de tiempo': marca de tiempo, 'address_book_id': 'id del registro de la libreta de direcciones' 'old_record': {'first_name': 'Jon', 'last_name': 'Doe' ...} }
Este enfoque se puede modificar para almacenar una variedad de versiones por documento. Pero este parece ser un enfoque más lento sin ninguna ventaja.
Almacene versiones como objeto serializado (JSON) adjunto a las entradas de la libreta de direcciones. No estoy seguro de cómo adjuntar dichos objetos a los documentos de MongoDB. Quizás como un conjunto de cuerdas. ( Modelado a partir de versiones de documentos simples con CouchDB )
fuente
Respuestas:
La primera gran pregunta al sumergirse en esto es "¿cómo desea almacenar los conjuntos de cambios" ?
Mi enfoque personal sería almacenar diffs. Debido a que la visualización de estas diferencias es realmente una acción especial, pondría las diferencias en una colección diferente de "historia".
Usaría la colección diferente para ahorrar espacio en la memoria. Por lo general, no desea un historial completo para una consulta simple. Entonces, al mantener el historial fuera del objeto, también puede mantenerlo fuera de la memoria de acceso común cuando se consultan esos datos.
Para hacerme la vida más fácil, haría que un documento de historia contuviera un diccionario de diferencias marcadas en el tiempo. Algo como esto:
Para hacer mi vida realmente fácil, 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 historial, por lo que puede anular fácilmente el
save()
método para realizar este cambio al mismo tiempo.ACTUALIZACIÓN: 2015-10
Parece que ahora hay una especificación para manejar diferencias JSON . Esto parece una forma más robusta de almacenar los diferenciales / cambios.
fuente
changes
es realmente fácil:db.hist.update({_id: ID}, {$set { changes.12345 : CHANGES } }, true)
esto realizará una actualización que solo cambiará los datos requeridos. Mongo crea documentos con "espacio de búfer" para manejar este tipo de cambio. También observa cómo cambian los documentos de una colección y modifica el tamaño del búfer para cada colección. Por lo tanto, MongoDB está diseñado para exactamente este tipo de cambio (agregar nueva propiedad / inserción a la matriz).Hay un esquema de versiones llamado "Vermongo" que aborda algunos aspectos que no se han tratado en las otras respuestas.
Uno de estos problemas son las actualizaciones simultáneas, otro es eliminar documentos.
Vermongo almacena copias completas de documentos en una colección oculta. Para algunos casos de uso, esto puede causar demasiada sobrecarga, pero creo que también simplifica muchas cosas.
https://github.com/thiloplanz/v7files/wiki/Vermongo
fuente
Aquí hay otra solución que usa un solo documento para la versión actual y todas las versiones anteriores:
data
Contiene todas las versiones. Ladata
matriz está ordenada , las nuevas versiones solo se$push
editarán hasta el final de la matriz.data.vid
es el id de la versión, que es un número incremental.Obtenga la versión más reciente:
Obtenga una versión específica por
vid
:Devuelve solo los campos especificados:
Insertar nueva versión: (y evitar la inserción / actualización concurrente)
2
es lavid
versión más reciente actual y3
es la nueva versión que se está insertando. Debido a que necesita las versiones más recientesvid
, es fácil obtener las siguientes versionesvid
:nextVID = oldVID + 1
.La
$and
condición asegurará, eso2
es lo últimovid
.De esta forma no hay necesidad de un índice único, pero la lógica de la aplicación debe ocuparse de incrementar la
vid
inserción en.Eliminar una versión específica:
¡Eso es!
(recuerde el límite de 16 MB por documento)
fuente
Si está buscando una solución lista para usar,
Mongoid ha incorporado versiones simples
http://mongoid.org/en/mongoid/docs/extras.html#versioning
mongoid-history es un complemento de Ruby que proporciona una solución significativamente más complicada con auditoría, deshacer y rehacer
https://github.com/aq1018/mongoid-history
fuente
Trabajé a través de esta solución que acomoda una versión publicada, borrador e histórica de los datos:
Explico el modelo más aquí: http://software.danielwatrous.com/representing-revision-data-in-mongodb/
Para aquellos que pueden implementar algo como esto en Java , aquí hay un ejemplo:
http://software.danielwatrous.com/using-java-to-work-with-versioned-data/
Incluyendo todo el código que puede bifurcar, si lo desea
https://github.com/dwatrous/mongodb-revision-objects
fuente
Si está utilizando mangosta, he encontrado que el siguiente complemento es una implementación útil del parche JSON formato
historia de parche de mangosta
fuente
Otra opción es usar el complemento mongoose-history .
fuente
He utilizado el siguiente paquete para un proyecto meteor / MongoDB, y funciona bien, la principal ventaja es que almacena el historial / revisiones dentro de una matriz en el mismo documento, por lo tanto, no es necesario tener publicaciones adicionales o middleware para acceder al historial de cambios . Puede admitir un número limitado de versiones anteriores (por ejemplo, las últimas diez versiones), también admite la concatenación de cambios (por lo que todos los cambios ocurridos dentro de un período específico estarán cubiertos por una revisión).
nicklozon / meteor-collection-revisions
Otra opción de sonido es usar Meteor Vermongo ( aquí )
fuente