我正在尽我所能优化数据库查找。据我了解,我的目标应该是针对唯一阶段是 IXScan 的获胜计划。但是我有一个包含日期键的字段,似乎我无法构建一个复合索引,在过滤“空”日期值时能够直接查找文档。
我的过滤器查询如下
{"$and":[
{"published":true},
{"soft_deleted_at":null}, # <-- this one's a date field, I need null values
{"another_filter":false},
{"yet_another_filter":false}
]}`
我尝试构建一个与该查询完全对应的部分索引(为了也节省一些索引内存,因为我知道我永远不必显示例如软删除的文档)
(请注意,代码是用 Ruby 编写的,但使用 Mongoid 可以毫无问题地转换为 MongoDB 语言)
index(
{
published: 1,
another_filter: 1,
soft_deleted_at: 1,
yet_another_filter: 1,
},
{
background: true,
name: 'Visible in search engine partial index',
partial_filter_expression: {
'$and': [
{"published":true},
{"soft_deleted_at":null},
{"another_filter":false},
{"yet_another_filter":false}
]
}
}
)
除了过滤器之外,这似乎运作良好soft_deleted_at
,因为我的获胜计划看起来像
=> {"stage"=>"FETCH",
"filter"=>{"soft_deleted_at"=>{"$eq"=>nil}},
"inputStage"=>
{"stage"=>"IXSCAN",
"keyPattern"=>{"published"=>1, "another_filter"=>1, "soft_deleted_at"=>1, "yet_another_filter"=>1},
"indexName"=>"Visible in search engine partial index",
"isMultiKey"=>false,
"multiKeyPaths"=>{"published"=>[], "another_filter"=>[], "soft_deleted_at"=>[], "yet_another_filter"=>[]},
"isUnique"=>false,
"isSparse"=>false,
"isPartial"=>true,
"indexVersion"=>2,
"direction"=>"forward",
"indexBounds"=>
{"published"=>["[true, true]"], "another_filter"=>["[false, false]"], "soft_deleted_at"=>["[null, null]"], "yet_another_filter"=>["[false, false]"]}}}
所以在这里我有这个额外的阶段"stage"=>"FETCH", "filter"=>{"soft_deleted_at"=>{"$eq"=>nil}},
,它基本上是手动过滤我的日期字段的空值。我希望这已经在部分索引中并且不需要更多过滤......我错了吗?
有什么办法可以避免这个额外的过滤阶段?