我们在Mongodb中对大部分系列进行了修改。选定的版本控制机制如下:
{ "docId" : 174, "v" : 1, "attr1": 165 } /*version 1 */
{ "docId" : 174, "v" : 2, "attr1": 165, "attr2": "A-1" }
{ "docId" : 174, "v" : 3, "attr1": 184, "attr2" : "A-1" }
因此,当我们执行查询时,我们总是需要以这种方式使用聚合框架来确保获取对象的最新版本:
db.docs.aggregate( [
{"$sort":{"docId":-1,"v":-1}},
{"$group":{"_id":"$docId","doc":{"$first":"$$ROOT"}}}
{"$match":{<query>}}
] );
这种方法的问题是,一旦完成分组,内存中的一组数据与您的集合无关,因此,您的索引无法使用。
因此,您的集合拥有的文档越多,查询就越慢。
有什么方法可以加快速度吗?
如果没有,我会考虑采用这篇好文章中定义的方法之一:http://www.askasya.com/post/trackversions/
答案 0 :(得分:0)
为了完成这个问题,我们选择了选项3:一个集合用于保留最新版本,一个集合用于保留历史版本。这里介绍了http://www.askasya.com/post/trackversions/,并在http://www.askasya.com/post/revisitversions/中找到了一些进一步的描述(包含一些不错的代码片段)。
它已经在生产中运行了6个月。到现在为止还挺好。以前的方法意味着我们总是使用聚合框架,一旦修改原始模式(使用$ group,$ project ...)就会远离索引,因为它不再匹配原始集合。随着数据的增长,这使我们的表现变得非常糟糕。
虽然问题已经消失,但采用新方法。我们90%的查询都是针对最新数据的,这意味着我们使用简单的ObjectId
作为标识符来定位集合,我们不再需要聚合框架,只需定期查找。
我们针对历史数据的查询始终包含id
和version
,因此可以将这些内容编入索引(我们将其包含为_id
,以便我们开箱即用),对这些集合的读取是同样快。这一点虽然不容忽视。在设计集合/模式在MongoDB中的样子时,应用程序中的读取模式至关重要,因此在做出此类决策时必须确保了解它们。