MongoDB大集合慢搜索

时间:2013-05-13 10:17:39

标签: python mongodb pymongo

我有大型mongodb集合(530万条目),每个条目都有list-field和一些额外的字段。例如:

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

我在字段c上有索引,我想对其进行搜索。此外,我想按此列表的所有排列进行搜索,例如我希望上面的对象位于查询"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:解释()关于较小版本的集合:

{
    "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"
}

1 个答案:

答案 0 :(得分:1)

Compound multikey indexes may only include one array field。您的字段 a c 都是数组,您无法创建索引 {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所说,你对复合指数有第三种选择。您可以重新设计架构并将 a 字段分解为更多字段,但您需要问自己要在此查询中执行的类型的排序。