あなたのインデックスにはインデックスを使用できないうえ、クエリ自体にいくつか問題があると思います。実際に問題がMongoDBで利用可能なすべての演算子についての理解が不足していると思います。
まず、ネストされた$状態が「ca」か「ok」のどちらかであるかどうかをチェックする必要はありません。なぜなら、それは全く同じことを行うstate:{$in:["ca", "ok"]}
に置き換えることができるからです。あなたのクエリは次のとおりです:
db.foo.find( {
"$or": [
{
"MODIFIED": {
"$gt": {
"sec": 1321419600,
"usec": 0
}
}
},
{
state:{$in:["ca", "ok"]}
}
],
"$and": [
{"fail": {"$ne": 1}},
{"generated": {"$exists": false}}
]
}).explain();
そしてあなたのインデックスにヒットします。 2番目の問題は、トップレベルの$と句が必要ないということです。 AND(OR(A, B), AND(C, D)) = AND(OR(A, B), C, D)
に注意してください。このクエリは、同じことを行います。
まだインデックスに当たる
db.foo.find( {
"$or": [
{
"MODIFIED": {
"$gt": {
"sec": 1321419600,
"usec": 0
}
}
},
{
state:{$in:["ca", "ok"]}
}
],
"fail": {"$ne": 1},
"generated": {"$exists": false}
}).explain();
:
{
"clauses" : [
{
"cursor" : "BtreeCursor MODIFIED_-1_state_1_fail_1_generated_1 multi",
"nscanned" : 0,
"nscannedObjects" : 0,
"n" : 0,
"millis" : 1,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : false,
"indexOnly" : false,
"indexBounds" : {
"MODIFIED" : [
[
{
"$maxElement" : 1
},
{
"sec" : 1321419600,
"usec" : 0
}
]
],
"state" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
],
"fail" : [
[
{
"$minElement" : 1
},
1
],
[
1,
{
"$maxElement" : 1
}
]
],
"generated" : [
[
null,
null
]
]
}
},
{
"cursor" : "BasicCursor",
"nscanned" : 0,
"nscannedObjects" : 0,
"n" : 0,
"millis" : 1,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : false,
"indexOnly" : false,
"indexBounds" : {
}
}
],
"nscanned" : 0,
"nscannedObjects" : 0,
"n" : 0,
"millis" : 1
}
役に立てば幸い!ところで、順序1の複合インデックスで最初のキーを開始し、-1を使用して2番目のキーを開始するのが少し一般的です。 -1は、前のフィールドに対する相対的な方向を決定するためだけに使用されることに注意してください。
すばらしい答えをありがとう。少しの教育と一緒に! – Petrogad
が調整され、すべてが優れています。はるかに高速。あなたの助けをもう一度ありがとう! – Petrogad
歓迎です;) –