我们有一个数据结构,我们有一个数组(实际上数组是子文档):
{ "someField" : ["value1", "value2"]}
我们构建了一个这样的查询:
db.collection.find({"someField":{
$in :["value1", "blah"],
$not : { $in : ["value2"]}}})
注意:我知道我们不需要第二个in
作为单个值,但我们需要支持倍数。
在someField
上有索引时。如果您只是查询in
并进行解释,则indexBounds
如下所示:
"indexBounds": {"someField:[["value1","value1"], ["blah", "blah"]]}
这对于有效使用索引非常有效。当您运行查询时,in
和not in
我们希望它将使用相同的边界,然后测试扫描对象的非条件。相反,indexBounds
看起来像这样:
"indexBounds": {"someField:[[{"$minElement":1}, "value2"], [value2 : {"$maxElement":1}]]}
此结果是扫描整个集合。
我们做错了吗?是否有其他方法来构造此查询。
目前我们可以解决的唯一解决方案是使用多个匹配语句进行聚合(一个包含首先包含部分,然后是独占部分)。有趣的是,如果你在聚合中进行{match, match}
,它们会被合并,你最终得到相同的结果,所以我们必须做{match, project, match}
以使每个匹配不同,以便第一个使用索引符合要求。
注意:我无法从我的工作系统中复制/粘贴,因此无法复制整个解释。
答案 0 :(得分:1)
我认为你有一个合适的索引,并以自然和正确的方式构建查询。您可以使用$nin
代替$not
$in
,但不会更改索引选择。这是SERVER-12281有用的实例,但该功能尚未实现。