このようなコレクションがあれば
{ a:1, b:1, c:1 }
{ a:1, b:1, c:2 }
{ a:1, b:1, c:3 }
{ a:1, b:2, c:1 }
... // all permutations up to:
{ a:3, b:3, c:3 }
このコレクションをランダムな順序で想像してみてください
({a:1,b:1,c:1}) の複合インデックスは次のようになります。
a: | 1 | 2 | 3 |
|-----------------+-----------------+-----------------|
b: | 1 | 2 | 3 | 1 | 2 | 3 | 1 | 2 | 3 |
|-----+-----+-----+-----+-----+-----+-----+-----+-----|
c: |1|2|3|1|2|3|1|2|3|1|2|3|1|2|3|1|2|3|1|2|3|1|2|3|1|2|3|
それぞれの a に対して、そのすべての b とそのすべての c が順番にありますね。
クエリ: db.xx.find({a:2}).sort({b:1})の場合、b 要素が a=2; の下にあることがわかります。インデックスは並べ替えに使用されます - "scanAndOrder" : Explain() でfalse クエリがdb.xx.find({a:2,c:{$in:[1,3]}}).sort({b:1})の場合、同じことが起こります。
しかし、これ: db.xx.find({a:{$in:[1,3]}}).sort({b:1}).explain()は"scanAndOrder" : trueを教えてくれます。 index はソートには使用されませんでした (クエリには使用されました) - 上記のスキーマからわかるように、a=[1,3] の "b" は連続していません。
そのため、インデックスの効率的なシーケンスは次のとおりです。
(1) exact matches (only one!)
(2) sort criteria
(3) matches that point to more than one document
あなたの場合、完全に一致するものはありません。どちらのクエリも、複数のドキュメントを返します。例でこれを試してみましょう。
db.xx.find({a:{$in:[1,3]},b:{$in:[1,3]}}).sort({c:1}).explain():を使用しますクエリにはインデックスを使用しますが、並べ替えには使用しないため、15 をスキャンして 12 個のオブジェクトを返します。
db.xx.find({b:{$in:[1,3]},c:{$in:[1,3]}}).sort({a:1}).explain():を使用しますクエリと並べ替えにはインデックスを使用しますが、21 をスキャンして 12 個のオブジェクトを返します。
どちらの方がよいですか?ユースケースによって異なります。通常、検索で多くのドキュメントが返される場合は、並べ替えでインデックスを使用する方が効率的ですが、(多数の中から) 少数しか返されない場合は、より効率的なスキャンを使用することをお勧めします。試してみて、explain() を使用して何が優れているかを確認してください
これは役に立ちますか?
よろしく
ロナルド
PS私はこれを使用してサンプルコレクションを作成しました:
[1,2,3].forEach(function(a){
[1,2,3].forEach(function(b){
[1,2,3].forEach(function(c){
db.xx.insert({a:a,b:b,c:c});
})
})
})