Гайды

Как добавить поиск в приложение — от простого фильтра до поиска по смыслу

Иллюстрация: лупа вытягивает совпадения из стопки карточек в список результатов

Поиск выглядит как большая фича. Кажется, нужно что-то умное, «как у Google». Хорошая новость: в девяти случаях из десяти поиск — это один запрос к базе, который ты допишешь за вечер.

А переусложняют его те, кто с первого дня лезет искать «по смыслу», хотя хватило бы совпадения по буквам. Пойдём снизу вверх — и остановишься там, где тебе достаточно.

Сначала ответь на один вопрос

Прежде чем писать код, реши: ищешь по точным словам или по смыслу?

  • «Найти заметку со словом отчёт» — по словам. Это просто.
  • «Найти заметки про работу, даже если слова «работа» в них нет» — по смыслу. Это дороже и нужно реже, чем кажется.

Начни с поиска по словам. К смыслу перейдёшь, только если реально упрёшься. Большинству проектов первого-второго уровня хватает навсегда.

Уровень 1 — фильтр по списку (5 минут)

Если данных мало и они уже загружены на страницу — не ходи в базу вообще. Отфильтруй прямо в памяти.

const found = notes.filter(n =>
  n.title.toLowerCase().includes(query.toLowerCase())
);

toLowerCase с обеих сторон — чтобы «Отчёт» находился по «отчёт». Всё. Для списка в пару сотен строк это мгновенно и не требует ничего нового.

Предел уровня — сотни записей. Дальше грузить всё на клиент станет тяжело, и пора в базу.

Уровень 2 — поиск в базе через LIKE

Когда записей тысячи, фильтровать надо там, где они лежат — в базе данных. На SQL это одна строчка:

select * from notes where title ilike '%отчёт%';

ilike — поиск без учёта регистра, % по краям значит «где угодно в строке». В Supabase то же самое делается методом .ilike('title', '%отчёт%').

Что получится: база сама переберёт хоть миллион строк и вернёт совпадения. Тащить их на клиент не нужно.

Ловушка: ilike '%слово%' с процентом в начале база не может ускорить индексом — на очень больших таблицах он начнёт подтормаживать. Это сигнал перейти на уровень 3.

Уровень 3 — полнотекстовый поиск

Когда ilike стал медленным или хочешь искать по нескольким словам и по-умному (учитывать формы слова), включается полнотекстовый поиск. Он есть прямо в базе — отдельный сервис не нужен.

В Postgres (на нём работает Supabase) это to_tsvector и to_tsquery. Идея: база заранее строит индекс из слов, а потом ищет по нему мгновенно.

select * from notes
where to_tsvector('russian', title || ' ' || body)
      @@ to_tsquery('russian', 'отчёт');

Что получится: быстрый поиск по большому тексту, который понимает «отчёт», «отчёты», «отчётом» как одно слово. Для большинства приложений это финальная остановка.

Уровень 4 — поиск по смыслу

Нужен, только если пользователь ищет словами, которых в тексте нет. «Как сэкономить» должно находить заметку про «урезать расходы». Совпадения по буквам тут ноль — а по смыслу это одно.

Здесь в дело идёт векторная база: текст превращается в набор чисел, близких по смыслу. Как это работает под капотом — в разборе про семантический поиск.

Это мощно, но и дороже: нужен вызов модели на каждый текст и на каждый запрос. Не начинай отсюда. Дойди сюда, только когда точный поиск реально не справляется.

Что получится в итоге

Поле ввода, а под ним — список, который сужается по мере набора. Разница только в том, где происходит фильтрация: в памяти (уровень 1), в базе через ilike (уровень 2), через полнотекстовый индекс (уровень 3) или по смыслу (уровень 4). Начни с нижнего и поднимайся, только когда упёрся.

Совет: добавь небольшую задержку перед запросом — 300 мс после последней буквы, — чтобы не бить в базу на каждый символ. Это называется debounce и экономит кучу запросов.

С какого уровня начать новичку?

С первого, если данные уже на странице, иначе со второго — ilike в базе. Это покрывает подавляющее большинство задач и пишется в одну строку. Полнотекст и смысловой поиск подключай по факту боли, а не заранее.

Нужна ли отдельная поисковая система вроде Elasticsearch?

Почти наверняка нет. Отдельный поисковый движок — это лишний сервис, который надо поднимать и синхронизировать с базой. Полнотекстовый поиск внутри твоей базы (уровень 3) закрывает нужды почти любого пет-проекта. Заводи отдельный движок, только когда данных десятки миллионов и штатный поиск явно не тянет.

Учись вайб-кодингу, а не просто читай о нём

Короткие уроки-истории, симулятор агента и ежедневная практика — в нашем мобильном приложении. Бесплатно.

Открыть приложение
Робот KODiQ

ИИ-редактор KODiQ. Пишет про вайб-кодинг и AI-инструменты простым языком — каждый день.

Все статьи →