Bonne question, j'y regardais aussi.
Créez une nouvelle version à chaque changement
J'ai découvert le module de versioning du pilote Mongoid pour Ruby. Je ne l'ai pas encore utilisé, mais d'après ce que j'ai pu trouver, il ajoute un numéro de version à chaque document. Les anciennes versions sont intégrées dans le document lui-même. Le principal inconvénient est que le document entier est dupliqué à chaque changement, ce qui entraîne beaucoup de contenu en double étant stocké lorsque vous traitez avec de grands documents. Cette approche est cependant valable lorsque vous traitez avec des documents de petite taille et/ou que vous ne mettez pas souvent à jour les documents.
Stocker uniquement les changements dans une nouvelle version
Une autre approche serait de stocker seulement les champs modifiés dans une nouvelle version. Ensuite, vous pouvez 'aplanir' votre historique pour reconstruire n'importe quelle version du document. Cependant, c'est assez complexe, car vous devez suivre les changements dans votre modèle et stocker les mises à jour et les suppressions d'une manière telle que votre application puisse reconstruire le document à jour. Cela peut être délicat, car vous travaillez avec des documents structurés plutôt que des tables SQL plates.
Stockez les changements à l'intérieur du document
Chaque champ peut également avoir une historique individuelle. Reconstruire des documents vers une version donnée est beaucoup plus facile de cette manière. Dans votre application, vous n'avez pas à suivre explicitement les changements, mais simplement créer une nouvelle version de la propriété lorsque vous en changez la valeur. Un document pourrait ressembler à ceci:
{
_id: "4c6b9456f61f000000007ba6"
title: [
{ version: 1, value: "Bonjour tout le monde" },
{ version: 6, value: "Foo" }
],
body: [
{ version: 1, value: "Ce truc fonctionne-t-il ?" },
{ version: 2, value: "Que devrais-je écrire ?" },
{ version: 6, value: "Voici le nouveau contenu" }
],
tags: [
{ version: 1, value: [ "test", "trivial" ] },
{ version: 6, value: [ "foo", "test" ] }
],
comments: [
{
author: "joe", // Champ sans version
body: [
{ version: 3, value: "Quelque chose de cool" }
]
},
{
author: "xxx",
body: [
{ version: 4, value: "Spam" },
{ version: 5, deleted: true }
]
},
{
author: "jim",
body: [
{ version: 7, value: "Pas mal" },
{ version: 8, value: "Pas mal du tout" }
]
}
]
}
Marquer une partie du document comme supprimée dans une version est encore quelque peu maladroit. Vous pourriez introduire un champ state
pour les parties qui peuvent être supprimées/restaurées depuis votre application:
{
author: "xxx",
body: [
{ version: 4, value: "Spam" }
],
state: [
{ version: 4, deleted: false },
{ version: 5, deleted: true }
]
}
Avec chacune de ces approches, vous pouvez stocker une version à jour et aplatie dans une collection et les données historiques dans une collection séparée. Cela devrait améliorer les temps de requête si vous vous intéressez seulement à la dernière version d'un document. Mais lorsque vous avez besoin à la fois de la dernière version et des données historiques, vous devrez effectuer deux requêtes, au lieu d'une seule. Ainsi, le choix entre utiliser une seule collection ou deux collections séparées devrait dépendre de la fréquence à laquelle votre application a besoin des versions historiques.
La plupart de cette réponse est juste un déversement de mes pensées, je n'ai pas encore essayé tout cela. En regardant en arrière, la première option est probablement la solution la plus facile et la meilleure, à moins que le surcroît de données dupliquées ne soit très significatif pour votre application. La deuxième option est assez complexe et probablement ne vaut pas l'effort. La troisième option est essentiellement une optimisation de la deuxième option et devrait être plus facile à mettre en œuvre, mais probablement ne mérite pas l'effort de mise en œuvre, à moins que vous ne puissiez vraiment pas opter pour la première option.
En attendant vos retours sur ce sujet et les solutions des autres personnes au problème :)
0 votes
Quel pilote de langue utilisez-vous ?
0 votes
Pas encore décidé - je peaufine encore et n'ai même pas encore finalisé le choix des back-ends (bien que MongoDB semble extrêmement probable). J'ai bricolé avec NoRM (C#), et j'aime certains des noms associés à ce projet, il semble donc très probable que ce soit le choix final.
2 votes
Je sais que cette question est ancienne, mais pour ceux qui recherchent le versionnage avec MongoDB, cette question SO est pertinente et, à mon avis, dispose de meilleures réponses.