38

最初のフィールドを優先し、次に2番目のフィールドを優先するように、mongoにクエリがあります。

次のようにクエリする必要があるとしましょう

db.col.find({category: A}).sort({updated: -1, rating: -1}).limit(10).explain()

そこで、次のインデックスを作成しました

db.col.ensureIndex({category: 1, rating: -1, updated: -1})

必要な数のオブジェクトをスキャンするだけでうまくいきまし10た。

しかし今、私はクエリする必要があります

db.col.find({category: { $ne: A}}).sort({updated: -1, rating: -1}).limit(10)

そこで、次のインデックスを作成しました。

 db.col.ensureIndex({rating: -1, updated: -1})

しかし、これはドキュメント全体のスキャンにつながり、私が作成するときに

 db.col.ensureIndex({ updated: -1 ,rating: -1})

スキャンするドキュメントの数が少なくなります。

複数のフィールドでの並べ替えと、その際に保持される順序について明確にしたいと思います。MongoDBドキュメントを読むと、並べ替えを実行する必要があるフィールドが最後のフィールドである必要があることは明らかです。$neこれが、上記のクエリで想定したケースです。私は何か間違ったことをしていますか?

4

4 に答える 4

46

The MongoDB query optimizer works by trying different plans to determine which approach works best for a given query. The winning plan for that query pattern is then cached for the next ~1,000 queries or until you do an explain().

To understand which query plans were considered, you should use explain(1), eg:

db.col.find({category:'A'}).sort({updated: -1}).explain(1)

The allPlans detail will show all plans that were compared.

If you run a query which is not very selective (for example, if many records match your criteria of {category: { $ne:'A'}}), it may be faster for MongoDB to find results using a BasicCursor (table scan) rather than matching against an index.

The order of fields in the query generally does not make a difference for the index selection (there are a few exceptions with range queries). The order of fields in a sort does affect the index selection. If your sort() criteria does not match the index order, the result data has to be re-sorted after the index is used (you should see scanAndOrder:true in the explain output if this happens).

It's also worth noting that MongoDB will only use one index per query (with the exception of $ors).

So if you are trying to optimize the query:

db.col.find({category:'A'}).sort({updated: -1, rating: -1})

You will want to include all three fields in the index:

db.col.ensureIndex({category: 1, updated: -1, rating: -1})

FYI, if you want to force a particular query to use an index (generally not needed or recommended), there is a hint() option you can try.

于 2012-09-21T11:58:02.080 に答える
1

それは本当ですが、複合インデックスでソートしているので、ここには2つの順序の層があります。

お気づきのように、インデックスの最初のフィールドがソートの最初のフィールドと一致すると、それが機能し、インデックスが表示されました。ただし、逆の方法で作業する場合はそうではありません。

そのため、独自の観察により、保持する必要のある順序は、最初から最後までのフィールドのクエリ順序です。mongoアナライザーは、インデックスに一致するようにフィールドを移動できる場合がありますが、通常は最初のフィールドに一致しようとしますが、一致しない場合はスキップします。

于 2012-09-20T17:28:39.370 に答える
0

このコードを試してみてください。最初に名前に基づいてデータを並べ替え、次に「名前」をキーホルダーに保持して「フィルター」を並べ替えます

 var cursor = db.collection('vc').find({   "name" :   { $in: [ /cpu/, /memo/ ]   }     }, { _id: 0, }).sort( { "name":1  ,  "filter": 1 } );
于 2017-01-12T09:14:49.890 に答える
0
Sort and Index Use¶

MongoDB can obtain the results of a sort operation from an index which includes the sort fields. MongoDB may use multiple indexes to support a sort operation if the sort uses the same indexes as the query predicate. ... Sort operations that use an index often have better performance than blocking sorts.

db.restaurants.find().sort( { "borough": 1, "_id": 1 } )

詳細: https ://docs.mongodb.com/manual/reference/method/cursor.sort/

于 2021-09-27T06:47:14.600 に答える