Python MongoDB大型集合慢速搜索

Python MongoDB大型集合慢速搜索,python,mongodb,pymongo,Python,Mongodb,Pymongo,我有大量的mongodb集合(530万个条目),每个条目都有列表字段和一些附加字段。例如: { "_id" : ObjectId("518d51c808beda0b70cffffa"), "a" : [ 0.00037, 0.00009 ], "b" : "Some long str", "c" : [ "element1", "element2", "element3" ] } 我在字段c上有索引,我想对其进行搜索。此外,我希望通过此列表的所有排列进行搜索,例如,我希望上

我有大量的mongodb集合(530万个条目),每个条目都有列表字段和一些附加字段。例如:

{ "_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: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"
}
。字段a和c都是数组,不能创建索引{c:1,a:-1},但可以创建索引{c:1}:

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

也可以考虑在查询中使用运算符,这样就可以消除在C字段上创建元素的排列的需要。但是,如果替换为,则查询将返回包含查询中未指定其他元素的文档的元素:

{u id:ObjectId(“518d51c808beda0b70cffffa”),
“a”:[0.00037,0.00009],
“b”:“一些长的str”,
“c”:[“元素1”、“元素2”、“元素3”、“元素4”]
}
要防止出现这种情况,可以将运算符与运算符组合使用:

results=collection.find({“c”:{“$all”:query,$size:len(query)}).sort(“a”,-1)
编辑:
正如@Sammaye所说,关于复合索引,您还有第三个选择。您可以重新设计架构并将a字段分解为更多字段,但您需要问问自己,您希望在此查询中执行哪种类型的排序。

您能给我们一个解释吗()?还有,集合上的索引是什么?是的,该查询没有使用索引,您可能需要添加
{c:1,a:-1}
,或者mongo Optimizer是否会看到它
{a:-1,c:1}
但我不确定乐观主义者是否会看到后一个索引,但它将生成一个按基数排序的$inrange@Sammaye出现错误
无法索引并行数组[c][a]
a
是数组类型吗?编辑:愚蠢的我我没有看问题顶部的文档结构我不确定
a
上的排序有多有用,你希望实现什么?我认为$in是他要找的操作员,我不知道问题的哪一部分让你拿出$all,此外,只有c上的索引不是最佳索引,因为它会创建扫描程序case@Sammaye,不可能创建包含多个数组字段的复合索引,因此他有两个选择。他可以使用索引进行扫描,也可以根本不使用索引。@Sammaye,他想按列表的所有排列进行搜索,所以他只创建一个巨大的查询来使用$in。他有第三个选择,模式转换。在这种情况下,这样的改变比考虑使用扫描设备要好。英语听起来更像是要按列表中的所有排列扫描文档,但这并不意味着文档需要包含“所有”排列。更重要的是,他希望如何搜索,子文档的排序可能无法提供他实际查找的排序(
a[0]
),也就是说,我也不知道你为什么建议在多键字段上排序是个好主意