我的mongodb数据库中有一组测试结果。数据库中的每个文档都包含版本信息,测试数据,日期,测试运行信息等...
版本在文档中分解并存储为单独的值。例如:{VER_MAJOR:“ 0”,VER_MINOR:“ 2”,VER_REVISION:“ 3”,VER_PATCH:“ 20}
我的应用程序希望能够指定特定版本并获取该文档以及基于该版本的前N个文档。
例如:
如果version = 0.2.3.20
和n = 5
,则结果将返回版本为0.2.3.20, 0.2.3.19, 0.2.3.18, 0.2.3.17, 0.2.3.16, 0.2.3.15
的文档
我想到的解决方案是:
创建一个新数据库,该数据库包含带有版本信息的文档并进行了排序。可以用来获取以前的N个版本,可以用来获取测试结果数据库中相应的N个文档。
像数字1一样在测试结果数据库中进行排序。尽管测试结果数据库很大,但这将花费很长时间。还可以考虑每次都按顺序插入。
像在选项1中那样创建另一个数据库似乎不是正确的方法。但是对测试结果数据库进行排序似乎会产生大量开销,我是否误认为我应该担心选项2会产生大量开销?我的印象是我必须查询整个数据库,然后在应用程序端对其进行排序。查询整个数据库似乎有些矫kill过正...
db.collection_name.find().sort([Paramaters for sorting])
答案 0 :(得分:1)
您完全正确的是,对整个数据集进行查询和排序将非常繁琐。我可能对此事过于关注,但我尝试在下面详细介绍所有内容。
首先,几对terminology nitpicks。我想您打算使用集合一词时,就是在使用数据库一词。区分这两个概念将有助于导航文档,并更好地理解MongoDB。
第二,重要的是要了解Collection中的文档没有固有的顺序。仅当从集合中检索文档时,例如在查询中指定.sort()
时,才应用将文档返回到应用程序的顺序。这意味着我们不需要将所有文档复制到其他集合中。我们只需要查询数据,以便仅以所需的顺序返回所需的数据。
现在是有趣的部分。该查询将如下所示:
db.test_results.find({
"VER_MAJOR" : "0",
"VER_MINOR" : "2",
"VER_REVISION" : "3",
"VER_PATCH" : { "$lte" : 20 }
}).sort({
"VER_PATCH" : -1
}).limit(N)
我们的查询在三个前导版本字段上具有直接匹配项,以将结果限制为仅这些值,即特定版本“ 0.2.3”。在$lte
上应用了范围VER_PATCH
过滤器,因为我们不仅需要一个补丁程序修订版。
然后,我们按VER_PATCH
对结果进行排序,以返回按补丁程序版本降序的结果。最后,limit运算符用于限制返回的文档数。
我们还没有完成!还记得您曾说过查询整个集合并将其在应用程序端进行排序感觉过大吗?好吧,如果此查询不存在索引,数据库将完全执行。
确定索引中字段的顺序时,应遵循equality-sort-match规则。在这种情况下,这将为我们提供索引:
{ "VER_MAJOR" : 1, "VER_MINOR" : 1, "VER_REVISION" : 1, "VER_PATCH" : 1 }
创建此索引将使查询只扫描返回的结果即可完成,同时避免了内存排序。可以找到更多信息here。