9

MongoDB での配列 (マルチキー) インデックス作成について調べていますが、ドキュメントをあまり見つけることができなかった次の質問があります。

サブドキュメントの配列のインデックス

したがって、次のような配列フィールドがあるとします。

{field : [
  {a : "1"}, 
  {b : "2"}, 
  {c : "3"}
  ]
}

私は個別に(両方を一緒にではなく)のみ照会しfield.afield.cいます。次の選択肢から選択できると思います。

  1. db.Collection.ensureIndex({field : 1});
  2. db.Collection.ensureIndex({field.a : 1}); db.Collection.ensureIndex({field.c : 1});

つまり、配列全体のインデックス。または埋め込みフィールドの 2 つのインデックス。今私の質問は次のとおりです。

  • オプション 1 で配列全体のインデックスをどのように視覚化しますか (それは有用ですか)? そのようなインデックスはどのようなクエリに役立ちますか?
  • 私が説明したクエリの状況を考えると、上記の 2 つのオプションのどちらが優れていますか? また、その理由は何ですか?
4

1 に答える 1

8

フィールド配列の a の値のみをクエリしている場合、両方のインデックスがある意味で、クエリのパフォーマンスを向上させるのに役立つことは間違いありません。

ただし、次の 3 つのクエリを見てください。

> db.zaid.save({field : [{a: 1}, {b: 2}, {c: 3}] });
> db.zaid.ensureIndex({field:1});
> db.zaid.ensureIndex({"field.a":1});

#Query 1
> db.zaid.find({"field.a":1})
{ "_id" : ObjectId("50b4be3403634cff61158dd0"), "field" : [ { "a" : 1 }, { "b" : 2 }, { "c" : 3 } ] }
> db.zaid.find({"field.a":1}).explain();
{
    "cursor" : "BtreeCursor field.a_1",
    "nscanned" : 1,
    "nscannedObjects" : 1,
    "n" : 1,
    "millis" : 0,
    "nYields" : 0,
    "nChunkSkips" : 0,
    "isMultiKey" : true,
    "indexOnly" : false,
    "indexBounds" : {
        "field.a" : [
            [
                1,
                1
            ]
        ]
    }
}

#Query 2
> db.zaid.find({"field.b":1}).explain();
{
    "cursor" : "BasicCursor",
    "nscanned" : 1,
    "nscannedObjects" : 1,
    "n" : 0,
    "millis" : 0,
    "nYields" : 0,
    "nChunkSkips" : 0,
    "isMultiKey" : false,
    "indexOnly" : false,
    "indexBounds" : {

    }
}

#Query 3
> db.zaid.find({"field":{b:1}}).explain();
{
    "cursor" : "BtreeCursor field_1",
    "nscanned" : 0,
    "nscannedObjects" : 0,
    "n" : 0,
    "millis" : 0,
    "nYields" : 0,
    "nChunkSkips" : 0,
    "isMultiKey" : true,
    "indexOnly" : false,
    "indexBounds" : {
        "field" : [
            [
                {
                    "b" : 1
                },
                {
                    "b" : 1
                }
            ]
        ]
    }
}

配列にインデックスを付けたにもかかわらず、2 番目のクエリにはインデックスがありませんが、3 番目のクエリにはインデックスがあることに注意してください。データのクエリ方法に基づいてインデックスを選択することは、インデックス自体が必要なものかどうかを検討することと同じくらい重要です。Mongo では、注意を怠ると、インデックスの構造がクエリのパフォーマンスに大きな違いをもたらす可能性があります。それがあなたの最初の質問を説明していると思います。

2 番目の質問はもう少しオープンエンドですが、答えはデータのクエリ方法にあると思います。「fields.a」の値の照合のみに関心がある場合は、後で必要になる可能性のある他のインデックス用にメモリに空きを確保する必要があります。ただし、配列内のこれらの項目のいずれかに対して同じようにクエリを実行する可能性があり、配列が無限に大きくなることはないと合理的に確信している場合 (時間の経過とともにバインドされていないサイズまで大きくなる可能性のある配列にインデックスを付けないでください。インデックス配列が BSON で 1024 バイトに達すると、ドキュメントにインデックスを付けることができなくなります)。その場合は、配列全体にインデックスを付ける必要があります。この例としては、ユーザーの手札の各カードを説明する配列を含む、トランプの手札のドキュメントが考えられます。

于 2012-11-27T13:34:51.433 に答える