{ item : null }
查询匹配包含该文件的文档item
字段,其值为null
或不包含item
字段。
我无法找到相关文档,但据我所知,两种情况(值null
或字段缺失)都存储在索引中null
。
因此,如果我db.orders.createIndex({item: 1})
然后db.orders.find({item: null})
,我希望IXSCAN
找到包含值为{{1}的item
字段的所有文档或者不包含null
字段,只包含那些文档。
那么为什么item
在执行db.orders.find({item: null}).explain()
后filter: {item: {$eq: null}}
阶段执行FETCH
?可能需要过滤哪些可能的文件?
IXSCAN
我认为可能会将{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "temp.orders",
"indexFilterSet" : false,
"parsedQuery" : {
"item" : {
"$eq" : null
}
},
"winningPlan" : {
"stage" : "FETCH",
"filter" : {
"item" : {
"$eq" : null
}
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"item" : 1
},
"indexName" : "item_1",
"isMultiKey" : false,
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 1,
"direction" : "forward",
"indexBounds" : {
"item" : [
"[null, null]"
]
}
}
},
"rejectedPlans" : [ ]
},
"serverInfo" : {
"host" : "Andys-MacBook-Pro-2.local",
"port" : 27017,
"version" : "3.2.8",
"gitVersion" : "ed70e33130c977bda0024c125b56d159573dbaf0"
},
"ok" : 1
}
值编入索引为undefined
,但简单的实验会对此进行排除:
null
答案 0 :(得分:1)
空等式匹配谓词(例如{"a.b": null}
)的语义非常复杂,因为字段可能包含单独索引扫描不足以提供正确结果的子文档。
服务器版本2.6.0改变了空相等的语义 匹配谓词,以便文档{a:[]}不再存在 被认为是查询谓词{“a.b”:null}的匹配(在之前的 服务器的这个版本被认为是匹配的 谓语)。这在2.6兼容性说明中有记录 “空比较”部分。
对于具有键模式{“a.b”:1}的索引,此文档{a:[]} 生成索引键{“”:null}。其他文件如{a:null}和 空文档{}也生成索引键{“”:null}。作为一个 结果,如果带有谓词{“a.b”:null}的查询使用此索引,则 查询系统无法告诉索引键{“”:null}是否或 不是关联的文档与谓词匹配。结果是, 分配INEXACT_FETCH边界而不是EXACT边界,因此a FETCH阶段被添加到查询执行树中。
补充说明:
- 文档{}为具有键模式{“a.b”:1}的索引生成索引键{“”:null}。
- 文档{a:[]}还为具有键模式{“a.b”:1}的索引生成索引键{“”:null}。
- 文档{}与查询{“a.b”:null}匹配。
- 文档{a:[]}与查询{“a.b”:null}不匹配。
醇>因此,查询{“a.b”:null}由带有键的索引回答 pattern {“a.b”:1}必须获取文档并重新检查谓词, 以确保文档{}包含在结果集中 并且文档{a:[]}未包含在结果集中。