2013-03-25 11 views
6

http://docs.mongodb.org/manual/core/indexes/#multikey-indexesから、マルチキーインデックスを使用して配列フィールドにインデックスを作成することは可能です。 http://docs.mongodb.org/manual/applications/aggregation/#pipeline-operators-and-indexesは、集約フレームワークでどのようにインデックスを使用できるかをいくつか示しています。ただし、配列フィールドに$unwindを実行して$groupを実行する必要がある場合があります。私の質問は、マルチキーインデックス(またはそのような配列フィールドを使用するインデックス)は、パイプラインの途中で操作された後も使用できるかどうかです。集約パイプラインとインデックス

答えて

11

一般的に、通常のクエリ($match$limit$sort、および$skip)に平坦化することができる唯一のパイプライン演算子は、コレクションのインデックスを使用することができます。これは、2.4で追加された$geoNear演算子がパイプラインの先頭になければならない理由の1つです。

$project$group、または$unwindを使用してドキュメントを変更すると、インデックスは有効でなくなりました。

$unwindの前に配列フィールドにインデックスを残しておくと、パイプライン化するドキュメントの選択を高速化し、選択したドキュメントを2番目の$matchでさらに細分化することができます。 tagsのインデックスで

{ tags: [ 'cat', 'bird', 'blue' ] } 

のような文書を考えてみましょう。

あなただけbで始まるグループにタグを望んでいたなら、あなたは次のように集約を行うことができます:

{ pipeline: [ 
     { $match : { tags : /^b/ } }, 
     { $unwind : '$tags' }, 
     { $match : { tags : /^b/ } }, 
     /* the rest */ 
    ] } 

最初$matchtagsにインデックスを使用して粗粒の試合を行います。

$unwindの後の2番目のマッチではインデックスを使用できません(上記のドキュメントは3つのドキュメントになりましたが、これらのドキュメントのそれぞれを評価して、 'cat'}を入力します)。

HTH - Rob。

うーん@Robが正しい答えを与えるが、私は彼が少し間違った道をあなたを導く可能性がどのように見てい
+0

答えをありがとう。しかし、私は "あなたが一度ドキュメントを変更すると、$ unwind'インデックスはもはや有効ではありません"答えの残りの部分と矛盾しています。なぜそういうのか説明できますか? – MervS

+0

申し訳ありませんが、より明確になっているはずです。私は2番目にそれを編集しようとしますが、最初の試合ではインデックスを使用し、2番目の試合ではインデックスを使用しません。 –

0

あなたは、配列のフィールドにインデックスを持っている場合、あなたはまだ前と後にそれを使用することができますパイプラインするドキュメントの選択をスピードアップし、次に選択されたドキュメントをさらに細かく調整するために$ unwindを使用します。

基本的に彼が与える例:

{ pipeline: [ 
     { $match : { tags : /^b/ } }, 
     { $unwind : '$tags' }, 
     { $match : { tags : /^b/ } }, 
     /* the rest */ 
    ] } 

$unwind過ぎマルチキーインデックスを使用しません。したがって、bで始まるタグ名を持つすべてのROOTドキュメントを検索することはできますが、$unwindにはアクセスできず、インデックスを使用して2番目の$matchにサブ文書をフィルタリングできます。

$matchは、突然変異の前のインデックスでのみ機能します。

基本的にドキュメントを突き詰めてパイプラインにロードすると、現時点でインデックスを使用することはほとんど不可能になります。

関連する問題