5

私は約 8000 万のドキュメントのコレクションを持っており、それぞれがtagsフィールドにタグの配列を格納しています。

{text: "blah blah blah...", tags: ["car", "auto", "automobile"]}

フィールドtagsはインデックス化されているため、当然、このようなクエリはほぼ瞬時に実行されます。

 db.documents.find({tags:"car"})

ただし、次のクエリはすべて非常に遅く、完了するまでに数分かかります。

 db.documents.find({tags:{$all:["car","phone"]}})
 db.documents.find({tags:{$in:["car","auto"]}})

配列に項目が 1 つしかない場合でも、問題は解決しません。

 db.documents.find({tags:{$all:["car"]}})  //very slow too

tags$all と $inはインデックス化されているため、非常に高速に動作できるはずだと思っていましたが、そうではないようです。なんで?

4

2 に答える 2

10

これは MongoDB の既知のバグであり、2.2 の時点ではまだ修正されていません。

を使用して複数のエントリを検索する場合、MongoDB はインデックス交差を実行しませ$all。インデックスを使用して配列内の最初のアイテムのみが検索され、一致したすべてのドキュメントのスキャンが実行されて結果がフィルタリングされます。

たとえば、クエリではdb.documents.find({tags:{$all:["car","phone"]}})、タグ「車」を含むすべてのドキュメントを取得してスキャンする必要があります。問題のコレクションには「車」でタグ付けされた 10 万件を超えるドキュメントが含まれているため、減速は驚くべきことではありません。

さらに悪いことに、MongoDB は、インデックス ルックアップのために $all 配列で最も表現の少ないアイテムを選択するという単純な最適化さえ実行しません。「車」のタグが付けられたドキュメントが 100000 件あり、「電話」のタグが付けられたドキュメントが 10 件ある場合、MongoDB は、結果を返すために 100000 件のドキュメントをスキャンする必要があります。{$all:["car", "phone"]}

参照: https://jira.mongodb.org/browse/SERVER-1000

于 2012-10-06T16:49:01.887 に答える
-1

追加したいのですが、 $in は高速です。実際、条件またはキーワードが 1 つだけの場合、$in は $all と同等ですが、$in は高速で、$all は低速で​​す。

したがって、$in を使用します。

于 2012-11-14T10:34:41.317 に答える