Я пытаюсь оптимизировать поиск в БД как можно лучше.Из того, что я понимаю, моя цель должна заключаться в том, чтобы нацелиться на выигрышный план, где единственным этапом является 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, но он без проблем переводит на язык MongoDB с использованием Mongoid)
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}},
, который в основном вручную фильтрует мое поле даты с нулевыми значениями.Я надеялся, что это уже будет в частичном индексе и не потребует дополнительной фильтрации ... я ошибся?
Есть ли способ избежать этой дополнительной стадии фильтрации?