Просьба «сделайте поиск по нашим данным» звучит одинаково для десяти карточек и для десяти миллионов документов, а решения за ней стоят несопоставимые. Разница не в объёме данных как таковом, а в том, сколько вы готовы платить за поддержание отдельной системы, которая умеет искать.
Считать это можно до того, как что-то поднято. Ниже модель, куда подставляются ваши значения.
Тупик: сравнить возможности по списку
Первое, что пробуют, — сравнить, что умеет отдельный поисковый движок и что умеет ваша база. Список получается убедительный: морфология, опечатки, ранжирование, подсветка, подсказки при вводе.
Это не помогает принять решение, потому что сравниваются не те величины. Возможности есть у обоих, вопрос в том, во сколько обходится их поддержание. Отдельный движок — это вторая система хранения ваших данных: её надо наполнять, синхронизировать, обновлять, мониторить и чинить, когда она разойдётся с основной базой. Список возможностей об этом не говорит ни слова.
Второй частый ход — посмотреть на цену управляемого сервиса и решить, что она подъёмная. Она обычно подъёмная. Но в смете это не единственная и, как правило, не главная строка.
Что считать
Считайте в часах, а деньги получите в конце, умножив на свою цену инженерного часа. Модель симметричная: у обоих путей есть цена, иначе расчёт подгонит ответ под желаемое.
Цена поиска в базе. Полнотекстовые возможности есть у современных баз, и для многих задач их достаточно. Расходы здесь: разовая настройка индекса и написание запросов, плюс регулярная работа, когда запросы начинают тормозить с ростом данных. Отдельной системы нет — значит, нет и синхронизации.
Цена отдельного движка. Разовая: развернуть, настроить схему полей и правила разбора текста, написать наполнение, перенести существующие данные. Регулярная и та, которую забывают: поддерживать синхронизацию с основной базой, обновлять версии, разбирать расхождения, дежурить, когда движок недоступен, и решать, что делать с поиском в это время.
Цена расхождения. У отдельного движка данные всегда немного отстают от основной базы. Насколько это допустимо — вопрос не технический: пользователь, не нашедший только что созданную запись, приходит в поддержку. Это тоже часы, просто не ваши.
Выгода. Считается не в возможностях, а в поведении людей: сколько запросов заканчивается ничем и сколько это стоит. Если поиск работает плохо и им не пользуются, выгода от улучшения нулевая независимо от того, что умеет движок.
Эту величину можно измерить до всякого выбора, и она обычно решает спор. Запишите за неделю: сколько всего поисковых запросов, сколько закончилось нулевым результатом, сколько — уходом со страницы без перехода дальше. Если запросов мало, никакой движок не окупится: вы улучшаете то, чем не пользуются. Если много и половина заканчивается ничем — у вас есть измеренная выгода, а не предположение.
Цена ошибки при переходе. Перенос поиска на отдельную систему редко бывает мгновенным: какое-то время работают оба пути, и данные надо держать согласованными в обоих. Этот период — отдельная строка, и он тем длиннее, чем больше мест в коде обращается к поиску.
Где проходит граница
Соотношение, которое обычно определяет ответ: отдельный движок окупается, когда поиск — основной способ добраться до данных, а не вспомогательный.
В каталоге, где пользователь приходит именно искать, качество поиска определяет, случится ли сделка. Там разница между «находит» и «почти находит» стоит больше всей поддержки движка.
В административной панели, где поиск нужен, чтобы найти известную запись по имени или номеру, база справится, а движок добавит расходов без выгоды: пользователь и так знает, что ищет.
Второй признак — характер запросов. Если люди ищут точное совпадение по короткому полю, отдельный движок не нужен. Если ищут словами, с опечатками, по нескольким полям сразу и ожидают, что сверху окажется самое подходящее, — база это тоже умеет, но настраивать ранжирование в ней дороже, и с ростом требований разрыв растёт.
Третий — объём и частота. Пока данные помещаются в память базы, а запросов немного, разница в скорости не видна. Она появляется на объёме, который перестал помещаться, и на нагрузке, где поисковые запросы начинают мешать основным.
Последнее стоит пояснить, потому что это самая частая техническая причина перехода. Тяжёлый поисковый запрос конкурирует за те же ресурсы, что и обычная работа приложения: пока их немного, это незаметно, но в какой-то момент поиск начинает замедлять оформление заказов. Вынос поиска в отдельную систему решает не задачу «искать лучше», а задачу «не мешать остальному» — и если болит именно это, сравнивать надо не возможности, а изоляцию нагрузки.
Промежуточный вариант, который часто пропускают
Между «в базе» и «отдельный движок» есть третий путь: улучшить поиск в базе, не поднимая ничего нового. Нормализация текста при записи, отдельная колонка с подготовленным для поиска представлением, синонимы таблицей, простое ранжирование по нескольким полям.
Это дешевле отдельной системы и покрывает заметную часть задач, ради которых её обычно поднимают. Проверять этот путь стоит первым — не потому, что он лучше, а потому что он отвечает на вопрос «а достаточно ли», после которого решение принимается уже осознанно.
Чего расчёт не покажет
Он не учитывает знания команды. Если движок уже стоит в компании и его умеют содержать, регулярная часть расходов у вас меньше — иногда настолько, что решение переворачивается.
Он не учитывает планы. Система, куда через год придут аналитика и подсказки при вводе, оценивается иначе, чем система, которой нужен один список.
И он не заменяет проверку на реальных запросах. Прежде чем считать, посмотрите, что люди на самом деле ищут: обычно оказывается, что половина запросов — это точные номера, для которых никакой движок не нужен.
Позиция редакции
Мы считаем, что отдельный поисковый движок стоит заводить, когда поиск — основной способ добраться до данных, и не стоит, когда он вспомогательный. Практический вывод: сначала посчитайте регулярные часы на синхронизацию и обновления, потом сравнивайте возможности. Обратный порядок всегда даёт ответ «нужен», потому что список возможностей всегда длиннее.
Мы неправы, если у вас уже есть команда, содержащая такой движок для других задач: там регулярная часть расходов размазывается, порог окупаемости падает, и заводить его для ещё одной коллекции разумно даже при вспомогательном поиске.