Входные данные: От клиента приходят товары с обязательной главной ценой и набором дополнительных цен. Каждому пользователю можно назначить одну из дополнительных цен.
Задача: Реализовать поиск по индивидуальной цене, с неточным вводом имени товара.
Решение: Берём какой-нибудь привычный поисковый движок (у меня это https://www.meilisearch.com/). Они позволяют индексировать сущность не только в формате "ключ-значение", но и с хранением json объектов. В моём случае товар представляет собой: { "id" 1, "name": "Товар", "prices": { "0": 100, "1": 200 "2": 100, }, } На этапе построения поискового образа заполняем у каждого товара все индивидуальные цены. Если индивидуальная цена к товару не существует - заполняем "дырку" главной ценой. Далее поиск и сортировка производится не по столцу "prices", а при помощи "prices.0", "prices.1", "prices.2" и т.д.
Таким образом жизненный цикл запроса на поиск такой:
- Определяем, какой ключ цен используется для конкретного запросившего пользователя.
- Ищем товары по имени и добавляем фильтрацию по индивидуальной цене. В случае с meilisearch, нужно не забыть добавить "filterable" на "prices". Если бы этот движок не позволял проворачивать такие фокусы со вложенными объектами, пришлось бы "на лету" во время построения индекса заводить "key-value" поля под каждый тип цен, либо представлять каждый товар с полем "price" и "price_type" в виде нескольких поисковых позиций.
Почему не попробовать реализовать это средствами sql? Подобные движки позволяют искать по очень неточному совпадению поискового запроса: "Ламачка" => "Лампочка". А еще очень гибко можно настраивать релевантность совпадения.