Saltar al contenido

MongoDB / NoSQL: mantenimiento del historial de cambios de documentos

Solución:

Buena pregunta, yo también estaba investigando esto.

Cree una nueva versión en cada cambio

Encontré el módulo de control de versiones del controlador Mongoid para Ruby. No lo he usado yo mismo, pero por lo que pude encontrar, agrega un número de versión a cada documento. Las versiones anteriores están incrustadas en el propio documento. El mayor inconveniente es que el todo el documento se duplica en cada cambio, lo que dará como resultado que se almacene una gran cantidad de contenido duplicado cuando se trata de documentos grandes. Sin embargo, este enfoque está bien cuando se trata de documentos de tamaño pequeño y / o no se actualizan documentos con mucha frecuencia.

Almacenar cambios solo en una nueva versión

Otro enfoque sería almacenar solo los campos modificados en una nueva versión. Luego, puede “aplanar” su historial para reconstruir cualquier versión del documento. Sin embargo, esto es bastante complejo, ya que necesita realizar un seguimiento de los cambios en su modelo y almacenar actualizaciones y eliminaciones de manera que su aplicación pueda reconstruir el documento actualizado. Esto puede ser complicado, ya que se trata de documentos estructurados en lugar de tablas SQL planas.

Almacenar cambios dentro del documento

Cada campo también puede tener un historial individual. Reconstruir documentos a una versión determinada es mucho más fácil de esta manera. En su aplicación, no tiene que realizar un seguimiento explícito de los cambios, sino simplemente crear una nueva versión de la propiedad cuando cambie su valor. Un documento podría verse así:

{
  _id: "4c6b9456f61f000000007ba6"
  title: [
    { version: 1, value: "Hello world" },
    { version: 6, value: "Foo" }
  ],
  body: [
    { version: 1, value: "Is this thing on?" },
    { version: 2, value: "What should I write?" },
    { version: 6, value: "This is the new body" }
  ],
  tags: [
    { version: 1, value: [ "test", "trivial" ] },
    { version: 6, value: [ "foo", "test" ] }
  ],
  comments: [
    {
      author: "joe", // Unversioned field
      body: [
        { version: 3, value: "Something cool" }
      ]
    },
    {
      author: "xxx",
      body: [
        { version: 4, value: "Spam" },
        { version: 5, deleted: true }
      ]
    },
    {
      author: "jim",
      body: [
        { version: 7, value: "Not bad" },
        { version: 8, value: "Not bad at all" }
      ]
    }
  ]
}

Sin embargo, marcar parte del documento como eliminado en una versión sigue siendo algo incómodo. Podrías introducir un state campo para las partes que se pueden eliminar / restaurar de su aplicación:

{
  author: "xxx",
  body: [
    { version: 4, value: "Spam" }
  ],
  state: [
    { version: 4, deleted: false },
    { version: 5, deleted: true }
  ]
}

Con cada uno de estos enfoques, puede almacenar una versión actualizada y compacta en una colección y los datos del historial en una colección separada. Esto debería mejorar los tiempos de consulta si solo está interesado en la última versión de un documento. Pero cuando necesite tanto la última versión como los datos históricos, deberá realizar dos consultas, en lugar de una. Por tanto, la elección de utilizar una sola colección frente a dos colecciones independientes debe depender de con qué frecuencia su aplicación necesita las versiones históricas.

La mayor parte de esta respuesta es solo un volcado cerebral de mis pensamientos, todavía no he probado nada de esto. Mirando hacia atrás, la primera opción es probablemente la mejor y más fácil solución, a menos que la sobrecarga de datos duplicados sea muy significativa para su aplicación. La segunda opción es bastante compleja y probablemente no valga la pena el esfuerzo. La tercera opción es básicamente una optimización de la opción dos y debería ser más fácil de implementar, pero probablemente no valga la pena el esfuerzo de implementación a menos que realmente no pueda optar por la opción uno.

Esperamos recibir comentarios sobre esto y las soluciones de otras personas al problema 🙂

Hemos implementado parcialmente esto en nuestro sitio y usamos las “Revisiones de la tienda en un documento separado” (y una base de datos separada). Escribimos una función personalizada para devolver las diferencias y la almacenamos. No es tan difícil y puede permitir la recuperación automatizada.

¿Por qué no una variación de Almacenar cambios dentro del documento ?

En lugar de almacenar versiones para cada par de claves, los pares de claves actuales en el documento siempre representan el estado más reciente y un ‘registro’ de cambios se almacena dentro de una matriz de historial. Solo aquellas claves que hayan cambiado desde la creación tendrán una entrada en el registro.

{
  _id: "4c6b9456f61f000000007ba6"
  title: "Bar",
  body: "Is this thing on?",
  tags: [ "test", "trivial" ],
  comments: [
    { key: 1, author: "joe", body: "Something cool" },
    { key: 2, author: "xxx", body: "Spam", deleted: true },
    { key: 3, author: "jim", body: "Not bad at all" }
  ],
  history: [
    { 
      who: "joe",
      when: 20160101,
      what: { title: "Foo", body: "What should I write?" }
    },
    { 
      who: "jim",
      when: 20160105,
      what: { tags: ["test", "test2"], comments: { key: 3, body: "Not baaad at all" }
    }
  ]
}
¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *