http://docs.mongodb.org/manual/core/indexes/#multikey-indexesから、マルチキーインデックスを使用して配列フィールドにインデックスを作成することができます。http://docs.mongodb.org/manual/applications/aggregation/#pipeline-operators-and-indexesには、集計フレームワークでインデックスを使用する方法のいくつかの方法がリストされています。$unwindただし、を実行するために配列フィールドでを実行する必要がある場合があります$group。私の質問は、マルチキーインデックス(またはそのような配列フィールドを使用する任意のインデックス)は、パイプラインの途中で操作された後でも使用できますか?
2 に答える
通常、コレクションのインデックスを使用できるのは、通常のクエリ(、、、、および)に$matchフラット化できるパイプライン演算子のみです。これが、2.4で追加された演算子がパイプラインの開始時になければならない理由の1つです。$limit$sort$skip$geoNear
、、を使用してドキュメントを変更すると、$projectインデックスは無効/使用できなくなります。$group$unwind
配列フィールドにインデックスがある場合でも、$unwindパイプラインへのドキュメントの選択を高速化する前にそれを使用して、選択したドキュメントを2番目のでさらに絞り込むことができ$matchます。
次のようなドキュメントを検討してください。
{ tags: [ 'cat', 'bird', 'blue' ] }
のインデックス付きtags。
で始まるタグのみをグループ化する場合bは、次のような集計を実行できます。
{ pipeline: [
{ $match : { tags : /^b/ } },
{ $unwind : '$tags' },
{ $match : { tags : /^b/ } },
/* the rest */
] }
1つ目$matchは、のインデックスを使用して粗粒度の一致を実行しますtags。
後の2番目の一致では$unwind、インデックスを使用できません(上記のドキュメントは3つのドキュメントになります)が、これらの各ドキュメントを評価して、作成される余分なドキュメントを除外できます({tags:'cat'}を削除するため)例)。
HTH-ロブ。
うーん@Robは正しい答えを出しますが、彼がどうやってあなたを間違った道に導くことができるかわかります:
配列フィールドにインデックスがある場合でも、$ unwindの前後でそれを使用して、パイプラインするドキュメントの選択を高速化し、選択したドキュメントをさらに絞り込むことができます。
基本的に彼が与える例:
{ pipeline: [
{ $match : { tags : /^b/ } },
{ $unwind : '$tags' },
{ $match : { tags : /^b/ } },
/* the rest */
] }
を過ぎたマルチキーインデックスは使用しません$unwind。したがって、タグ名がで始まるすべてのROOTドキュメントを検索することはできますが、インデックスを使用して2番目のサブドキュメントを検索して除外するbことはできません。$unwind$match
は$match、ミューテーションの前のインデックスでのみ機能します。
したがって、基本的に、ドキュメントを変更してパイプラインにロードすると、現在、インデックスを使用することはほとんど不可能になります。