3

この質問は、MongoDB でインデックスを使用して、個々のサブレベルにインデックスを付けることなく、ネストされたドキュメントで何かを検索する方法に関するものです。基本的に次のようなMongoDBのコレクション「テスト」があります。

{
"_id" : ObjectId("50fdd7d71d41c82875a5b6c1"),
"othercol" : "bladiebla",
"scenario" : {
        "1" : { [1,2,3] },
        "2" : { [4,5,6] }
}}

シナリオには複数のキーがあり、各ドキュメントにはシナリオの任意のサブセット (つまり、なしからサブセット、すべて) を含めることができます。また: Python の辞書として必要なので、シナリオを配列にすることはできません。「シナリオ」フィールドに索引を作成しました。
私の問題は、特定の値を持つドキュメントをフィルタリングして、コレクションを選択したいということです。したがって、これは機能的にうまく機能します:

db.test.find({"scenario.1": {$exists: true}})

ただし、シナリオに追加したインデックスは使用しません。「scenario.1」にインデックスを付けた場合にのみ、インデックスが使用されます。しかし、私は数千 (またはそれ以上) のシナリオを持つことができます (そして、コレクション自体には 100.000 のレコードがあります)。
だから私は代替案を試しました:

db.test.find({"scenario": "1"}) 

これはシナリオでインデックスを使用しますが、結果は返しません。シナリオを配列にすると、同じインデックスの問題が発生します。

私の質問は明確ですか?ここで最高のパフォーマンスを達成する方法を教えてもらえますか?

Ps 私はこれを見ました: MongoDB でネストされたインデックスを作成する方法? しかし、私の場合、その解決策は不可能です(シナリオの量のため)

4

2 に答える 2

5

個々のフィールドではなく完全なオブジェクトをフィルタリングする場合にのみ使用されるため、サブオブジェクトにインデックスを配置することは、この場合は役に立ちません (バイナリ BLOB 比較と考えてください)scenarioscenario

可能性のある各フィールド ( "scenario.1""sceanario.2"など) にインデックスを追加するか、次のようにしてスキーマを作り直して動的キーを取り除く必要があります。

{
"_id" : ObjectId("50fdd7d71d41c82875a5b6c1"),
"othercol" : "bladiebla",
"scenario" : [
    { id: "1", value: [1,2,3] },
    { id: "2", value: [4,5,6] }
}}

scenario.id次に、実行する必要があるクエリをサポートするために単一のインデックスを追加できます。

配列ではなく辞書である必要があると言ったことは知っていますがscenario、どのように選択肢があるかわかりません。

于 2013-01-23T02:04:59.760 に答える
2

Johnny HK の回答は、説明がわかりやすい回答であり、一般的な場合に使用する必要があります。多くのシナリオが必要で、複雑なクエリを必要としない場合に、問題を解決するための回避策を提案します。シナリオ フィールドの下に値を保持する代わりに、そのフィールドの下にシナリオの ID を保持し、ドキュメント内の別のフィールドとして値を保持し、シナリオ ID をこのフィールドのキーとして使用します。

例:

{
"_id" : ObjectId("50fdd7d71d41c82875a5b6c1"),
"othercol" : "bladiebla",
"scenario" : [ "1", "2"],
"scenario_1": [1,2,3],
"scenario_2": [4,5,6]
}}

このスキーマでは、シナリオのインデックスを使用して特定のシナリオを見つけることができます。ただし、特定のシナリオ値を照会する必要がある場合は、各シナリオ値フィールド (シナリオ 1、シナリオ 2 など) にインデックスが必要です。各フィールドにインデックスが必要な場合は、元のスキーマを変更しないでください。ネストされたフィールドごとに疎インデックスを使用すると、インデックスのサイズを減らすのに役立つ場合があります。

于 2013-01-23T07:50:53.290 に答える