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:在较小版本的集合上解释():

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

复合多键索引只能包含一个数组字段。您的字段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 所说,您对复合索引有第三种选择。您可以重新设计架构并将a字段分解为更多字段,但您需要问自己要在此查询中执行哪种类型的排序。

于 2013-05-13T18:02:04.130 回答