您能否分享一下您如何在MongoDB中实现数据版本控制? (我已经问了similar question regarding Cassandra . 如果您有任何想法,哪个数据库更好,请分享)
假设我需要在简单的地址簿中对记录进行版本控制 . (地址簿记录存储为平面json对象) . 我期待历史:
-
将不经常使用
-
将一次性使用以"time machine"方式呈现它
-
赢了't be more versions than few hundred to a single record. history won'吨到期 .
我正在考虑以下方法:
- 创建新的对象集合以存储记录的历史记录或记录的更改 . 它将为每个版本存储一个对象,并引用地址簿条目 . 这些记录如下:
{
'_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' ...}
}
可以修改此方法以存储每个文档的版本数组 . 但这似乎是没有任何优势的较慢的方法 .
- 将版本存储为附加到地址簿条目的序列化(JSON)对象 . 我不确定如何将这些对象附加到MongoDB文档 . 也许是一个字符串数组 . (Modelled after Simple Document Versioning with CouchDB)
9 回答
有一种称为“Vermongo”的版本控制方案,它解决了其他答复中未涉及的一些方面 .
其中一个问题是并发更新,另一个是删除文档 .
Vermongo将完整的文档副本存储在阴影集合中 . 对于某些用例,这可能会导致过多的开销,但我认为它也简化了很多事情 .
https://github.com/thiloplanz/v7files/wiki/Vermongo
潜入这个问题的第一个重要问题是"how do you want to store changesets"?
Diffs?
整个记录副本?
我个人的方法是存储差异 . 因为这些差异的显示实际上是一个特殊的动作,我会把差异放在一个不同的“历史”集合中 .
我会使用不同的集合来节省内存空间 . 您通常不希望简单查询的完整历史记录 . 因此,通过将历史记录保留在对象之外,您还可以在查询数据时将其保留在常用内存中 .
为了让我的生活变得轻松,我会制作一份包含时间标记差异字典的历史文档 . 像这样的东西:
为了让我的生活变得非常简单,我将使用我用来访问我的数据的DataObjects(EntityWrapper,无论如何) . 通常,这些对象具有某种形式的历史记录,因此您可以轻松地覆盖
save()
方法以同时进行此更改 .UPDATE: 2015-10
看起来现在有a spec for handling JSON diffs . 这似乎是一种更健壮的方式来存储差异/变化 .
这是针对当前版本和所有旧版本使用单个文档的另一种解决方案:
data
包含 all 版本 .data
数组是 ordered ,新版本只能在数组末尾获得$push
.data.vid
是版本ID,是递增的数字 .Get the most recent version:
Get a specific version by vid:
Return only specified fields:
Insert new version: (并防止并发插入/更新)
2
是当前最新版本的vid
,3
是插入的新版本 . 因为您需要最新版本的vid
,所以's easy to do get the next version' svid
:nextVID = oldVID + 1
.$and
条件将确保2
是最新的vid
.这种方式不需要唯一索引,但应用程序逻辑必须注意增加插入
vid
.Remove a specific version:
而已!
(记住每个文件限制16MB)
如果您正在寻找即时解决方案 -
Mongoid内置了简单版本
http://mongoid.org/en/mongoid/docs/extras.html#versioning
mongoid-history是一个Ruby插件,它提供了一个复杂的解决方案,包括审计,撤销和重做
https://github.com/aq1018/mongoid-history
我通过这个解决方案来处理数据的已发布,草稿和历史版本:
我在这里进一步解释模型:http://software.danielwatrous.com/representing-revision-data-in-mongodb/
对于那些可能在 Java 中实现类似内容的人,这是一个例子:
http://software.danielwatrous.com/using-java-to-work-with-versioned-data/
如果你愿意,可以包括你可以分叉的所有代码
https://github.com/dwatrous/mongodb-revision-objects
如果您使用的是mongoose,我发现以下插件是JSON Patch格式的有用实现
mongoose-patch-history
另一种选择是使用mongoose-history插件 .
我使用下面的包用于meteor / MongoDB项目,它运行良好,主要优点是它将数据库中的历史/修订存储在同一文档中,因此无需额外的出版物或中间件来访问更改历史记录 . 它可以支持有限数量的先前版本(例如前十个版本),它还支持更改连接(因此在特定时间段内发生的所有更改都将由一个修订版覆盖) .
nicklozon/meteor-collection-revisions
另一个声音选项是使用Meteor Vermongo(here)
尝试使用Javers . 好图书馆 .