2

大規模な mongodb コレクション (530 万エントリ) があり、各エントリにはリスト フィールドといくつかの追加フィールドがあります。例えば:

{ "_id" : ObjectId("518d51c808beda0b70cffffa"), 
  "a" : [ 0.00037, 0.00009 ], 
  "b" : "Some long str", 
  "c" : [ "element1", "element2", "element3" ] 
}

フィールドにインデックスがcあり、それを検索したい。さらに、このリストのすべての順列で検索したい。たとえば、上記のオブジェクトを query の検索結果に含めたい"c": ["element3", "element2", "element1"]

私はこのようにpymongoを使用します:

from itertools import permutations
...
query = ['element1', 'element2', 'element3']
query_permutations = list(permutations(query, len(query)))
results = collection.find({"c": {"$in": query_permutations}}).sort("a", -1)

速くする方法はありますか?

UPD:コレクションの小さいバージョンでの Explain() :

{
    "cursor" : "BasicCursor",
    "isMultiKey" : false,
    "n" : 11053,
    "nscannedObjects" : 11053,
    "nscanned" : 11053,
    "nscannedObjectsAllPlans" : 11053,
    "nscannedAllPlans" : 11053,
    "scanAndOrder" : false,
    "indexOnly" : false,
    "nYields" : 0,
    "nChunkSkips" : 0,
    "millis" : 41,
    "indexBounds" : {

    },
    "server" : "machine.local:27017"
}
4

1 に答える 1

1

複合マルチキー インデックスには、1 つの配列フィールドのみを含めることができます。フィールドacは両方とも配列であり、インデックス{c:1,a:-1}を作成することはできませんが、インデックス{c:1}を作成できます。

db.collection.ensureIndex({c: 1})

また、クエリで演算子$allを使用することを検討すると、フィールドcで要素の順列を作成する必要がなくなります。ただし、$in$allに置き換えると、クエリは、クエリで指定されていない他の要素を持つドキュメントで要素を返します。

{ "_id" : ObjectId("518d51c808beda0b70cffffa"),
  "a" : [ 0.00037, 0.00009 ],
  "b" : "Some long str",
  "c" : [ "element1", "element2", "element3", "element4" ]
}

これを防ぐには、演算子$allを演算子$sizeと組み合わせることができます。

results = collection.find({"c": {"$all": query, "$size": len(query)}}).sort("a", -1)

編集:

@Sammayeが述べたように、複合インデックスについて3番目の選択肢があります。スキーマを再設計しフィールドをさらに多くのフィールドに分割することはできますが、このクエリで実行する並べ替えの種類を自問する必要があります。

于 2013-05-13T18:02:04.130 に答える