我有大型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"
}
答案 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 字段分解为更多字段,但您需要问自己要在此查询中执行的类型的排序。