Давайте в качестве примера рассмотрим распознавание адресов. Этакий аналог дадата.ру ))
Возьмем за основу несколько адресов:
город Москва улица академика Петра Анохина
город Москва улица Юрия Кондратюка
город Киев улица Гната Юры
Московская область город Химки улица Московская
Пользователь может написать слова в любом порядке, делать сокращения (ак. Антохина или Ю. Кондратюка), видоизменять слова (Юрия = Юры), ошибаться в типах (перепутать проезд и переулок, или проспект с улицей), делать очепятки.
С помощью полезной нагрузки можно было бы в одном поле проставить для каждого термина вес, которым бы мы смогли влиять на релевантность:
город^30 Москва^100 улица^20 Юрия^70 Кондратюка^100
город^30 Киев^100 улица^20 Гната^70 Юры^100
Тип компонента адреса (город, улица...) имел бы меньший вес, должности (академика, генерала...) более высокий вес, имена еще больше вес, а точные названия и фамилии самый большой вес. Получается в одной строке есть ключи и дополнения к ключам для поднятия суммарного веса.
Если не делать разбивку по весу, то при запросе "Юры Кондратюка" мы получим вышеописанные две строки, которые будут иметь одинаковый score при similarity = boolean.
Я сейчас даю очень упрощенный пример, просто для обозначения сути проблемы!
Как можно решить задачу с подобным поиском? Делать энное количество полей в документе: отдельно под тип (город, улица), должности, имена, фамилии, варианты написания, сокращения и тд. Дальше делать multi_match запрос с most_fields типом. Это уже усложняет задачу по индексации! Сейчас мы знаем, что нужно к примеру 5 полей, а через месяц будут новые данные и полей будет не 5, а 10. Значит пересоздавать mappings и индекс.
А теперь давайте посмотрим на 4 пример: Московская область город Химки улица Московская - тут у нас слово Московская повторяется дважды. Значит нам нужно делать еще один should запрос match_phrase_prefix и большим slop, чтобы учесть, что это разные термины - рескоринг (Improving Performance | Elasticsearch: The Definitive Guide [master] | Elastic)
Но! Поскольку у нас строка адреса разнесена на составляющие поля, чтобы задать вес каждому слову, то мы не сможем сделать match_phrase_prefix - значит нам нужно добавить в документ еще одно поле, в котором бы мы писали всю строку целиком.
Как итог:
- вместо одного поля нужно заводить энное количество!
- проблемное масштабирование и индексация
- перечислять все поля при поиске с указанием веса для каждого поля
- все равно создавать дополнительное поле для специфических "подзапросов", в котором хранить все слова
- размер индекса больше
- как мне кажется - скорость поиска будет все же меньше, особенно при длинных запросах