7

次のようなドキュメントを含むテスト MongoDB コレクション「sampleCollection」を作成しました。

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

フィールド「stringField」にインデックスがあります。私が実行すると

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フレームワークを使用しており、クエリ構造の使用がリポジトリを作成する唯一の方法です。したがって、インデックス付きデータを完全に無視するデータベースがあります。

それが正しいか?それとも私は何かを誤解しましたか?

4

2 に答える 2

5

それは面白かったです私はそれがバグであるかどうかを決めることはできません。それはあなた次第です:

2 つの使用可能な構文があります: http://docs.mongodb.org/manual/reference/operator/query/

使用する場合:

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

また、

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

うまく動作します。

ソリューションを使用する場合 (他の構文):

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

の出力

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

インデックスを使用しないクエリのように表示されます

インデックスに .hint も使用すると、結果が省略されます。:)(つまり、私は本当に理解していません)

幸いなことに、これらの操作には別の構文もあります。次を使用できます。

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

正しい出力が得られ、インデックスの使用法が示されます。$hint にも同様の構文があります。

ここでドキュメントを確認できます: http://docs.mongodb.org/manual/reference/meta-query-operators/

これは本当に興味深いので、プロファイラーを有効にしました。

私は、年齢のインデックスを持つ構造体に _id と age フィールドのみを持つ約 250k ドキュメントのテスト コレクション (queryTst) を作成しました。

このクエリの場合:

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" : {

    },

プロファイラー ログ: 最初の

{
    "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" : ""
}

2番目の場合:

{
    "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() が混合構文でテーブルスキャンを引き起こすことを意味します。

于 2013-01-30T20:49:42.483 に答える
4

これはバグではありません。たまたまあなたと同じ質問があり、mongodbの問題として報告しようとしていましたが、ドキュメントを読んで、カーソルメソッド( Explain() など)を混ぜてはいけないと指定されていますこのクエリ形式では、このページで提供されている例のように、$explain を使用する必要があります。

http://docs.mongodb.org/manual/reference/operator/query/

于 2013-05-02T00:20:21.643 に答える