Вопрос про индексацию,
например, документы сейчас имеют такой вид: {x: 'a', y: 'b', z:'c'}
где, a,b,c - это по сути, split строки, a-b-c. Однако, регулярно, приходят строки со значениями(и это нормально), где префикса a - нет, то есть строки вида b-c.
Тогда документы сохраняются в виде, {'y:' 'b', 'z':'c'}. Так как поиск предусматривается и по полной форме {x: 'a', 'y:' 'b', 'z':'c'}, и по частичной. { 'y:' 'b', 'z':'c'}. То построен индекс {y:1, z:1, x:1}, такой порядок, ввиду того, что y более уникален, чем z.
Так вот, так как индекс сразу по 3 полям, то в поиске(агрегации), когда ищут данные по b-c (то есть на вход дают только значения для y,z), я использую для поля x такое добавление в match:
'$or': [{'x': {'$exists': false}},
{'x': {'$exists': true}}]
И вот думаю, если для случаев когда приходит документ без префикса, в короткой форме, может быть всё таки лучше сохранять документ в "полной" форме, а в значение этого "префикса" назначать, на пример, -1 - (такого точно не может прийти во входных данных).
То есть документы примут вид для таких случаев:
{x: -1, y: 'b', z:'c'}.
И вот вопрос, у меня получится что в поле может быть как "целое" -1, так и строка, при полной форме входной строки. Или всё такие сохранять в x -1 как строку? И при поиска. когда на вход подадут только y и z в match будет такое:
'$or': [{'x': -1},
{'x': {'$ne':-1}}]
И вопросы такие
Будет ли такое эффективней чем exists,
Нормально ли смешивать два типа, в одних документах целое, в других строка, в контексте построения индекса.
По размеру документа, для целого монга сразу будет занимать сколько то байт, а для строки, будет увеличиваться документ на 2 сколько байт, если будет только '-1'. Потому как такое изменение повлечет и увеличение документов, и увеличение индекса.
Документов, 40 млрд, и на таком количестве разница в байтах, будет видна.
не очень понятно зачем надо добавлять условия вида
'$or': [{'x': {'$exists': false}},
{'x': {'$exists': true}}]
т.к. они всегда истинны и имеют смысл разве что для полей посреди составного индекса, чтобы попытаться триггернуть covered выборку.
Будет ли эффективнее замена экзист - да, т.к. надо монга дополнительно читает документ с диска чтобы проверить этот факт если это не sparse индекс (https://www.mongodb.com/docs/manual/reference/operator/query/exists/#use-a-sparse-index-to-improve--exists-performance)
По размеру числа почти всегда дадут меньший размер индекса по сравнению со строками и соответственно снизят требования к памяти и как следствие нагрузку на систему изза объемов гоняемых данных между диском и оперативой.
Однако в вашем случае где есть всегда выборка по y+z и иногда к ним добавляется еще x, мне например видится вариант строки вида "y-z:x" которая покрывает все указанные выборки (дефис и двоеточие тут символы разделители). Возможнос такой индекс даст больший импакт чем суррогат из трех интовых полей