MongoDB $ query运算符会忽略索引吗? [英] MongoDB $query operator ignores index?

查看:66
本文介绍了MongoDB $ query运算符会忽略索引吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个包含以下内容的测试MongoDB集合"sampleCollection":

I created a test MongoDB collection "sampleCollection" with documents which looks like:

 "_id" : ObjectId("510929e041cb2179b41ace1c"),
 "stringField" : "Random string0",
 "longField" : NumberLong(886)

,并且在字段"stringField"上具有索引. 当我执行

and has index on field "stringField". When I execute

db.sampleCollection.find({"stringField":"Random string0"}).explain()

一切正常:

 "cursor" : "BtreeCursor stringField_1",
 "isMultiKey" : false,
 "n" : 2,
 "nscannedObjects" : 2,
 "nscanned" : 2,
 "nscannedObjectsAllPlans" : 2,
 "nscannedAllPlans" : 2,
 "scanAndOrder" : false,
 "indexOnly" : false,
 "nYields" : 0,
 "nChunkSkips" : 0,
 "millis" : 0,
 "indexBounds" : {
         "stringField" : [
                 [
                         "Random string0",
                         "Random string0"
                 ]
         ]
 }

但是

db.sampleCollection.find({$query:{"stringField":"Random string0"}}).explain()

得到我

"cursor" : "BasicCursor",
"isMultiKey" : false,
"n" : 0,
"nscannedObjects" : 4,
"nscanned" : 4,
"nscannedObjectsAllPlans" : 4,
"nscannedAllPlans" : 4,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 0,
"indexBounds" : {

}

这似乎不是问题,但是我在生产和使用查询构造时使用 org.springframework.data.mongodb 框架是编写存储库的唯一方法. 因此,我有一个完全忽略索引数据的数据库.

This is not looks like a problem, but I'm using org.springframework.data.mongodb framework in production and usage of query constructions is an only way to write repositories. And thus I have a db which completely ignores indexed data.

对吗?还是我误会了什么?

Is it correct? Or I misunderstood something?

推荐答案

真可笑,我不能决定说这是一个错误,还是取决于您:

That was funny i cannot decide to say it is a bug or not it is up to you:

有两种可用的语法: http://docs.mongodb.org/manual/reference/operator/查询/

使用时:

db.collection.find( { age : 25 } )

也将

db.collection.find( { age : 25 } ).explain()
db.collection.find( { age : 25 } ).hint(someindex)

做得好.

使用解决方案时(另一种语法):

When you using your solution (the other syntax):

db.collection.find( { $query: { age : 25 } } )

db.sampleCollection.find({$query:{"stringField":"Random string0"}}).explain()

将显示为查询不使用索引

Will show like the query not using the index

如果您还使用.hint作为索引,它将忽略结果. :)(那是我不太了解)

if you also use .hint for the index it will omit the result. :) (That is i do not really understand)

幸运的是,这些操作也有另一种语法:您可以使用:

Fortunately there is another syntax for these operations too: you can use:

db.sampleCollection.find({$query:{"stringField":"Random string0"}, $explain:1})

它将具有正确的输出,并为我显示了索引的用法. $ hint也有类似的语法.

it will have the right output and showed for me the usage of the index. Also there is similar syntax for $hint.

您可以在此处查看文档: http://docs.mongodb.org/manual/reference /meta-query-operators/

You can check the documentation here: http://docs.mongodb.org/manual/reference/meta-query-operators/

我发现这真的很有趣,所以我打开了探查器:

I found this really interesting so i turned on the profiler:

我制作了一个测试集合(queryTst),其中包含约250k个文档,每个文档仅包含_id和结构中的age字段,并带有年龄索引.

i made a test collection (queryTst) with around 250k docs each with only _id and an age field in the structure with an index on age.

对于此查询:

db.queryTst.find({$query:{"age":16},$explain:1})

我得到了:

{
    "cursor" : "BtreeCursor age_1",
    "isMultiKey" : false,
    "n" : 2,
    "nscannedObjects" : 2,
    "nscanned" : 2,
    "nscannedObjectsAllPlans" : 2,
    "nscannedAllPlans" : 2,
    "scanAndOrder" : false,
    "indexOnly" : false,
    "nYields" : 0,
    "nChunkSkips" : 0,
    "millis" : 0,
    "indexBounds" : {
        "age" : [
            [
                16,
                16
            ]
        ]
    },
    "allPlans" : [
        {
            "cursor" : "BtreeCursor age_1",
            "n" : 2,
            "nscannedObjects" : 2,
            "nscanned" : 2,
            "indexBounds" : {
                "age" : [
                    [
                        16,
                        16
                    ]
                ]
            }
        }
    ],
    "oldPlan" : {
        "cursor" : "BtreeCursor age_1",
        "indexBounds" : {
            "age" : [
                [
                    16,
                    16
                ]
            ]
        }
    },
    "server" : ""
}

为此:

 db.queryTst.find({$query:{"age":16},$explain:1}).explain()

我得到了:

"cursor" : "BasicCursor",
    "isMultiKey" : false,
    "n" : 0,
    "nscannedObjects" : 250011,
    "nscanned" : 250011,
    "nscannedObjectsAllPlans" : 250011,
    "nscannedAllPlans" : 250011,
    "scanAndOrder" : false,
    "indexOnly" : false,
    "nYields" : 0,
    "nChunkSkips" : 0,
    "millis" : 103,
    "indexBounds" : {

    },

在分析器日志中:第一个

in the profiler log: for the first

{
    "ts" : ISODate("2013-01-30T20:35:40.526Z"),
    "op" : "query",
    "ns" : "test.queryTst",
    "query" : {
        "$query" : {
            "age" : 16
        },
        "$explain" : 1
    },
    "ntoreturn" : 0,
    "ntoskip" : 0,
    "nscanned" : 2,
    "keyUpdates" : 0,
    "numYield" : 0,
    "lockStats" : {
        "timeLockedMicros" : {
            "r" : NumberLong(368),
            "w" : NumberLong(0)
        },
        "timeAcquiringMicros" : {
            "r" : NumberLong(8),
            "w" : NumberLong(5)
        }
    },
    "nreturned" : 1,
    "responseLength" : 567,
    "millis" : 0,
    "client" : "127.0.0.1",
    "user" : ""
}

第二个:

{
    "ts" : ISODate("2013-01-30T20:35:47.715Z"),
    "op" : "query",
    "ns" : "test.queryTst",
    "query" : {
        "query" : {
            "$query" : {
                "age" : 16
            },
            "$explain" : 1
        },
        "$explain" : true
    },
    "ntoreturn" : 0,
    "ntoskip" : 0,
    "nscanned" : 250011,
    "keyUpdates" : 0,
    "numYield" : 0,
    "lockStats" : {
        "timeLockedMicros" : {
            "r" : NumberLong(104092),
            "w" : NumberLong(0)
        },
        "timeAcquiringMicros" : {
            "r" : NumberLong(13),
            "w" : NumberLong(5)
        }
    },
    "nreturned" : 1,
    "responseLength" : 373,
    "millis" : 104,
    "client" : "127.0.0.1",
    "user" : ""
}

这在某种程度上对我意味着,explain()会导致以混合语法进行表扫描.

which somehow means to me that is the explain() cause the table scan in the mixed syntax.

这篇关于MongoDB $ query运算符会忽略索引吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆