使用索引使用$ NOT进行完整集合扫描

时间:2014-11-10 16:40:31

标签: mongodb indexing

我们有一个数据结构,我们有一个数组(实际上数组是子文档):

{ "someField" : ["value1", "value2"]}

我们构建了一个这样的查询:

db.collection.find({"someField":{ 
                       $in :["value1", "blah"], 
                       $not : { $in : ["value2"]}}})

注意:我知道我们不需要第二个in作为单个值,但我们需要支持倍数。

someField上有索引时。如果您只是查询in并进行解释,则indexBounds如下所示:

  "indexBounds": {"someField:[["value1","value1"], ["blah", "blah"]]}

这对于有效使用索引非常有效。当您运行查询时,innot in我们希望它将使用相同的边界,然后测试扫描对象的非条件。相反,indexBounds看起来像这样:

  "indexBounds": {"someField:[[{"$minElement":1}, "value2"], [value2 : {"$maxElement":1}]]}

此结果是扫描整个集合。

我们做错了吗?是否有其他方法来构造此查询。

目前我们可以解决的唯一解决方案是使用多个匹配语句进行聚合(一个包含首先包含部分,然后是独占部分)。有趣的是,如果你在聚合中进行{match, match},它们会被合并,你最终得到相同的结果,所以我们必须做{match, project, match}以使每个匹配不同,以便第一个使用索引符合要求。

注意:我无法从我的工作系统中复制/粘贴,因此无法复制整个解释。

1 个答案:

答案 0 :(得分:1)

我认为你有一个合适的索引,并以自然和正确的方式构建查询。您可以使用$nin代替$not $in,但不会更改索引选择。这是SERVER-12281有用的实例,但该功能尚未实现。