2

次のようなドキュメントのコレクションで、MongoDB で Meteor を使用しています。

{a: 'a1',
 b: 'b1',
 c: {
     d: 'd1',
     e: 'e1'
    }
}

最初に次のようなインデックスを作成しました。 collection._ensureIndex({'c.d': 1});

そして、次のようなクエリを実行しました: collection.find({c: {d: 'd1'}). これらは非常にゆっくりと実行され、explain() でデバッグしたときに、インデックスを使用していないことに気付きました。

OTOH、次のようなクエリを実行した場合: collection.find({'c.d': 'd1'})、Mongoインデックスを使用します。

サブドキュメント全体にインデックスを付けるようにインデックスを変更しました。つまりcollection._ensureIndex({c: 1})、最初のクエリがインデックスにヒットするようになりました。

私の質問は、これはバグですか、それとも機能ですか? 私の印象では、JSON では 2 つの表記法は同等であり、率直に言って、データベースは 2 つのクエリ用語が同じフィールドを参照していることを認識し、適切なインデックスを使用するほどスマートであることが期待されます。

サブドキュメント全体をインデックス化する回避策に関する私の懸念は、最終的に、そのサブドキュメントには、インデックス化する必要のないフィールドがさらに含まれる可能性があり、不要なインデックス用語を保持する時間と RAM を浪費するのは最適ではないように思われることです。

これがバグでない場合、Mongo にネストされたオブジェクトの構文を認識させ、インデックスを適切に使用させる方法はありますか?

4

1 に答える 1

1

mongoのドキュメントを確認した後、私はそれを理解したと思います。基本的に、これら 2 つのセマンティクスに違いがあります。基本的に、 query の最初の形式では、mongo はサブドキュメント全体{c: {d: d1}}を指定していると想定します。したがって、 subdocument がある場合、一致しません。{c: {d: d1, e: e1}}

OTOH、クエリの 2 番目の形式は{'c.d': d1}、サブドキュメント内の 1 つのフィールドでのみ一致を指定していることを意味します。これは、サブ文書に他のフィールドまたはサブサブ文書全体がある場合でも一致します。

この違いはインデックスにまで及びます。_ensureIndex({c: 1})とは 2 つの異なるインデックスであり、最初のインデックスはサブドキュメント全体にインデックスを付けますが、表記法_ensureIndex({'c.d': 1})を使用して個々のフィールドをクエリする場合は使用されません。c.d

于 2016-05-17T03:55:08.800 に答える