你能分享一下你如何在MongoDB中实现数据版本控制的想法吗?(关于卡桑德拉,我也问过类似的问题。如果你有任何想法,哪个db更好,请分享)
假设我需要对一个简单地址簿中的记录进行版本化。(地址簿记录存储为平面json对象)。我希望历史:
是否会不经常使用
会被一次性用“时间机器”的方式呈现出来吗
一张唱片的版本不会超过几百个。
历史不会终结。
我正在考虑以下方法:
Create a new object collection to store history of records or changes to the records. It would store one object per version with a reference to the address book entry. Such records would looks as follows:
{
'_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' ...}
}
This approach can be modified to store an array of versions per document. But this seems to be slower approach without any advantages.
Store versions as serialized (JSON) object attached to address book entries. I'm not sure how to attach such objects to MongoDB documents. Perhaps as an array of strings.
(Modelled after Simple Document Versioning with CouchDB)
我通过这个解决方案,容纳了数据的公开版本、草稿版本和历史版本:
{
published: {},
draft: {},
history: {
"1" : {
metadata: <value>,
document: {}
},
...
}
}
我将在这里进一步解释该模型: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
下面是另一种解决方案,使用一个文档针对当前版本和所有旧版本:
{
_id: ObjectId("..."),
data: [
{ vid: 1, content: "foo" },
{ vid: 2, content: "bar" }
]
}
数据包含所有版本。数据数组是有序的,新版本只会被$推到数组的末尾。数据。Vid是版本id,是一个递增的数字。
获取最新版本:
find(
{ "_id":ObjectId("...") },
{ "data":{ $slice:-1 } }
)
通过vid获取特定版本:
find(
{ "_id":ObjectId("...") },
{ "data":{ $elemMatch:{ "vid":1 } } }
)
只返回指定的字段:
find(
{ "_id":ObjectId("...") },
{ "data":{ $elemMatch:{ "vid":1 } }, "data.content":1 }
)
插入新版本:(并防止并发插入/更新)
update(
{
"_id":ObjectId("..."),
$and:[
{ "data.vid":{ $not:{ $gt:2 } } },
{ "data.vid":2 }
]
},
{ $push:{ "data":{ "vid":3, "content":"baz" } } }
)
2是当前最新版本的vid, 3是插入的新版本。因为你需要最新版本的vid,所以很容易得到下一个版本的vid: nextVID = oldVID + 1。
$和条件将确保2是最新的vid。
这样就不需要唯一的索引,但是应用程序逻辑必须负责在插入时增加vid。
删除特定版本:
update(
{ "_id":ObjectId("...") },
{ $pull:{ "data":{ "vid":2 } } }
)
就是这样!
(请记住每个文档限制为16MB)