0

此处涵盖的查询的 mongo 文档讨论了查询和投影,如果您想要涵盖的查询,只需关闭投影中的 _id 字段。如果您需要 _id 字段并且仍然想要覆盖查询的效率(indexOnly = True)怎么办?

 db.collection.ensureIndex({field1:1,_id:1})
 db.collection.getIndexKeys()

 [{
    "_id" : 1
},
{
    "field1" : 1
},
{
    "field1" : 1,
    "_id" : 1
}]

db.collection.find({field1:{$regex:/^\s/}},{field1:1,_id:1}).explain()
{
"cursor" : "BtreeCursor fieldname",
"isMultiKey" : false,
"n" : 3582,
"nscannedObjects" : 3582,
"nscanned" : 130511408,
"nscannedObjectsAllPlans" : 3582,
"nscannedAllPlans" : 130511408,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 20,
"nChunkSkips" : 0,
"millis" : 158705,
"indexBounds" : {
    "cdr3_aa" : [
        [
            "",
            {

            }
        ]
    ]
},
"server" : localhost}

当然,如果我在投影上关闭 _id,IndexOnly 会返回 true,并且查询速度很快。我究竟做错了什么?

编辑 - 我通过摆脱对空间的不区分大小写,添加 ^ 来加快查询速度,但 IndexOnly : False,从而提高了效率。我不明白为什么它不是真的。

4

2 回答 2

1

文档

只有当正则表达式在字符串的开头(即^)有一个锚点并且是区分大小写的匹配时,$regex 才能有效地使用索引。此外,虽然/^a/、/^a.*//^a.*$/匹配等效字符串,但它们具有不同的性能特征。如果存在适当的索引,则所有这些表达式都使用索引;但是,/^a.*//^a.*$/较慢。/^a/匹配前缀后可以停止扫描。

在您的情况下,您使用正则表达式,i这意味着不区分大小写的匹配。因此,您应该i从正则表达式中删除并从字段的开头开始搜索。

\s顺便说一句,我不明白您的搜索条件:在不区分大小写的字段中寻找一个空格字符?

于 2013-09-11T07:44:12.750 回答
0

不太清楚为什么,但似乎您的查询使用的是{ field1: 1 }索引而不是{ field1: 1, _id: 1 }索引。您可以尝试使用提示运行查询吗?

db.collection.find( { field1: {$regex:/^\s/} }, { field1: 1, _id: 1 } ).hint( { field1: 1, _id: 1 } ).explain()

可能是查询优化器最初选择了 { field1: 1 } 索引并且没有重新评估各种计划。有关查询优化器及其如何选择计划的说明,请参阅http://docs.mongodb.org/manual/core/query-plans/ 。

于 2013-09-12T03:35:21.183 回答