在MongoDB中实现数据版本控制的方法
你能分享一下你的想法吗?你将如何在MongoDB中实现数据版本化? (我问过关于Cassandra的类似问题,如果你有任何想法,哪个db更好,请分享)
假设我需要在简单的地址簿中记录版本记录。 (地址簿记录存储为扁平json对象)。 我期待的历史:
我正在考虑以下方法:
创建一个新的对象集合来存储记录的历史或对记录的更改。 它将在每个版本中存储一个对象,并引用地址簿条目。 这些记录如下所示:
{ '_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文档。 也许是一串字符串。 (使用CouchDB进行简单文档版本控制后进行建模)
第一个大问题是,“如何存储变更集”?
我个人的做法是存储差异。 由于这些差异的显示确实是一个特殊的行为,我会将差异放在不同的“历史”集合中。
我会使用不同的集合来节省内存空间。 您通常不需要完整的历史记录以进行简单的查询。 因此,通过将历史记录保留在对象之外,您还可以在查询数据时将其保留在通常访问的内存之外。
为了让我的生活更轻松,我会让历史文档包含时间戳差异字典。 像这样的东西:
{
_id : "id of address book record",
changes : {
1234567 : { "city" : "Omaha", "state" : "Nebraska" },
1234568 : { "city" : "Kansas City", "state" : "Missouri" }
}
}
为了让我的生活变得非常简单,我将使用DataObjects(EntityWrapper,无论什么)来访问我的数据。 通常,这些对象具有某种形式的历史记录,因此您可以轻松地重写save()
方法以同时进行此更改。
更新:2015-10
它看起来像现在有一个处理JSON差异的规范。 这似乎是一种更强大的方式来存储差异/变化。
有一个名为“Vermongo”的版本控制方案,它解决了其他答复中尚未处理的一些方面。
其中一个问题是并发更新,另一个是删除文档。
Vermongo将完整的文档副本存储在影集中。 对于某些使用情况来说,这可能会造成太多的开销,但我认为这也简化了很多事情。
https://github.com/thiloplanz/v7files/wiki/Vermongo
这是另一种使用单个文档的当前版本和所有旧版本的解决方案:
{
_id: ObjectId("..."),
data: [
{ vid: 1, content: "foo" },
{ vid: 2, content: "bar" }
]
}
data
包含所有版本。 data
数组是有序的 ,新版本将只获得$push
到数组的末尾。 data.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
。
$and
条件将确保2
是最新的vid
。
这样就不需要唯一的索引,但应用程序逻辑必须注意在插入时增加vid
。
删除特定版本:
update(
{ "_id":ObjectId("...") },
{ $pull:{ "data":{ "vid":2 } } }
)
而已!
(请记住每个文档限制16MB)
链接地址: http://www.djcxy.com/p/86371.html上一篇: Ways to implement data versioning in MongoDB
下一篇: What does MongoDB not being ACID compliant really mean?