对空值的匹配会导致MongoDB的查询需要回表并进行过滤,也就是说不被索引覆盖
https://mongoplayground.net/p/EDTWuPebIwm
db.collection.aggregate([
{
$match: {
cheese: null
}
},
{
$project: {
_id: 0,
butter: 1
}
}
]).explain("queryPlanner")
MongoDB会返回在上述查询中字段cheese缺失或其值为null的文档。
MongoDB还在索引中把null当作该文档字段缺失或等于null时的值来存储。
因此,由于查询会返回字段缺失或为null的文档,为什么还需要先获取再过滤?当查询匹配 "cheese: { $exists: false }" 时存在歧义。但对于 "cheese: null",则不存在歧义。
"filter": {
"cheese": {
"$eq": null
}
},
能否解释一下,上面的查询为何无法被索引覆盖?
是否有办法让查询像应该那样被覆盖,因为索引包含了覆盖该查询所需的所有信息?
解决方案
The index entry doesn't store a BSON with field names, only the values for the indexed fields. It doesn't distinguish between a missing field and a field with null value. Both are stored as a null key.
筛选阶段 $match: { cheese: null } 能匹配两者,但投影可能返回 {} 或 { cheese: null },而这些信息不在索引键中。于是就必须获取BSON文档。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。