Як додати пошук до застосунку: від простих фільтрів до повнотекстового пошуку
Щоб додати пошук до застосунку, почніть із найпростішого, що працює: поле пошуку, яке викликає серверний маршрут, що фільтрує рядки бази даних за збігом запиту з кількома стовпцями, плюс фільтри для таких речей, як категорія чи ціна. Коли цього не вистачає — потрібне ранжування релевантності, пошук за основами слів або багато записів, — перейдіть до повнотекстового пошуку вашої бази даних, а до хостованого пошукового сервісу переходьте лише тоді, коли потрібна висока терпимість до помилок або миттєві результати на дуже великих даних. Що б ви не обрали, пошук має враховувати дозволи: користувачі ніколи не повинні знаходити записи, які їм не дозволено бачити.
Що означає «пошук» для вашого застосунку
Пошук охоплює кілька різних речей, і більшості застосунків потрібно більше за одне:
- Пошук за ключовими словами: поле для тексту — «знайди оголошення зі словом „сад“».
- Фільтри: структуровані вибори — категорія, місто, діапазон цін, дата, статус.
- Сортування: найновіші, найдешевші, найрелевантніші.
- Автодоповнення: підказки під час набору.
- Терпимість до помилок: «рестораан» усе одно знаходить «ресторан».
Для каталогу, дошки вакансій чи магазину фільтри часто важливіші за текстове поле. Визначте, що з цього вам справді потрібно, перш ніж обирати інструмент.
Ваші варіанти
| Підхід | Як працює | Підходить для | Обмеження |
|---|---|---|---|
| Фільтрація в браузері | Завантажити список і фільтрувати його в JavaScript | Невеликі публічні списки (кілька сотень елементів) | Надсилає всі дані кожному відвідувачу; повільно з великими списками |
| Пошук за шаблоном у базі даних | Серверний запит на кшталт «назва містить текст», без урахування регістру | Невеликі та середні застосунки, інструменти адміністратора | Немає ранжування; може сповільнюватися на великих таблицях; немає пошуку за основами слів |
| Повнотекстовий пошук у базі даних | Postgres індексує слова та ранжує збіги | Більшість застосунків із великою кількістю контенту | Слабкий до помилок, якщо не додати нечіткий збіг |
| Нечіткий збіг (триграми) | Postgres порівнює послідовності символів за схожістю | Імена, короткі поля, терпимість до помилок | Потрібне розширення та індекс; потрібне налаштування |
| Хостований пошуковий сервіс | Окремий сервіс індексує ваші дані (Algolia, Meilisearch, Typesense, Elasticsearch та інші) | Великі каталоги, миттєвий пошук, висока терпимість до помилок | Ще один сервіс, який треба синхронізувати, оплачувати та захищати |
Якщо ваші дані вже зберігаються в Postgres, його вбудований повнотекстовий пошук — сильний проміжний варіант. Він розбиває текст на слова, зводить їх до основ (тож «running» знаходить «run»), ігнорує поширені слова та може ранжувати результати за ступенем збігу. З правильним індексом він залишається швидким на великих таблицях.
Приклади промптів
Простий старт:
Додай поле пошуку та фільтри на сторінку оголошень. Пошук має шукати запит у заголовку й описі без урахування регістру. Фільтри: категорія (випадаючий список), місто (випадаючий список) і максимальна ціна. Виконуй пошук на сервері через API-маршрут з пагінацією, 20 результатів на сторінку. Зберігай пошук і фільтри в URL, щоб результатами можна було поділитися і працювала кнопка «назад». Покажи зрозумілий порожній стан, коли нічого не знайдено.
Перехід на повнотекстовий пошук:
Переведи пошук оголошень на повнотекстовий пошук Postgres за заголовком (з вищою вагою) та описом. Додай потрібний індекс, ранжуй результати за релевантністю та збережи наявні фільтри й пагінацію. Не змінюй жодних наявних даних.
Додавання терпимості до помилок для імен:
Додай нечіткий збіг за назвою бізнесу, щоб невеликі помилки все одно знаходили результати. Використовуй схожість за триграмами, якщо вона доступна, з індексом, а якщо ні — поверни поточний пошук.
Покроково
- Складіть список того, що люди шукають. Які поля (заголовок, опис, теги, назва)? Які фільтри? Якщо можете, запитайте кількох реальних користувачів.
- Почніть із сервера. Додайте API-маршрут, який приймає запит і фільтри та повертає одну сторінку результатів. Не завантажуйте все в браузер.
- Застосовуйте дозволи в запиті. Якщо користувачі бачать лише свої записи або лише опубліковані, ця умова має бути в тому ж запиті, що й пошук.
- Додайте пагінацію з самого початку — номери сторінок або «завантажити ще».
- Зберігайте стан пошуку в URL (наприклад,
?q=garden&city=leeds). Посилання можна ділитися, кнопка «назад» працює, а пошукові системи можуть індексувати відфільтровані сторінки, якщо ви цього хочете. - Додайте затримку для пошуку під час набору. Чекайте кілька сотень мілісекунд після завершення набору, перш ніж надсилати запит, щоб не відправляти запит на кожне натискання клавіші.
- Додайте індекси, коли знаєте, за якими стовпцями фільтруєте й шукаєте.
- Удосконалюйте: спершу повнотекстовий пошук, потім нечіткий збіг, потім хостований сервіс — лише тоді, коли простіший крок не задовольняє реальних користувачів.
- Тестуйте на правдоподібних даних: сотні чи тисячі рядків, незвичайні символи, порожні запити, дуже довгі запити, інші мови, якщо ви їх підтримуєте.
Типові помилки
- Завантаження всієї таблиці в браузер. Нормально для 50 елементів, болісно для 50 000, і це розкриває кожен запис — включно з тими, які користувачеві не можна бачити.
- Пошук, що ігнорує дозволи. Пошук — поширене джерело витоку: приватний запис або чернетка з'являється, бо запит пошуку забув умову «лише мої» чи «лише опубліковані».
- Побудова SQL із сирого введення користувача. Завжди використовуйте параметризовані запити. ШІ-конструктор зазвичай так і робить, але перевіряйте, чи не склеюються рядки.
- Немає порожнього стану. Повідомлення «Нічого не знайдено» з підказкою (очистити фільтри, перевірити написання) утримує людей від виходу.
- Немає індексів. Пошук із тестовими даними виглядає нормально, а з часом, коли дані реальні, сповільнюється.
- Одразу переходити до пошукового сервісу. Тоді доводиться тримати другу копію даних синхронізованою, обробляти видалення й захищати ще один набір ключів — часто без помітної вигоди.
- Забути про мобільні пристрої. Фільтри мають вміщуватися на телефоні; панель фільтрів або згорнута панель зазвичай працює краще, ніж бічна панель.
Чек-лист
- Ви знаєте, які поля шукаються і які фільтри існують
- Пошук виконується на сервері й повертає результати з пагінацією
- Запит застосовує ті самі дозволи, що й решта застосунку
- Введення користувача передається як параметри, ніколи не склеюється в SQL
- Стан пошуку зберігається в URL
- Набір тексту має затримку
- Стовпці, за якими шукають і фільтрують, проіндексовано
- Порожні стани, відсутність результатів і помилки зрозумілі
- Протестовано з реалістичними обсягами даних і неохайним введенням
Додавання пошуку з Mythex
У застосунку, створеному на Mythex, дані зазвичай зберігаються в базі даних Postgres проєкту, тож можна почати з наведених вище промптів: спершу пошук за шаблоном, потім повнотекстовий пошук Postgres, коли потрібне ранжування. Якщо ви хочете хостований пошуковий сервіс, використайте власний обліковий запис і ключ, збережіть його як секрет проєкту й попросіть агента індексувати та виконувати запити з сервера, як описано в Інтеграція з будь-яким API.
Пошук — основа багатьох застосунків: дивіться як створити сайт-каталог, як створити дошку вакансій і як створити маркетплейс, щоб побачити, як він вписується в решту продукту.
Запитання
Який найпростіший спосіб додати пошук до застосунку?
Якщо ваші дані зберігаються в базі даних, найпростіший старт — це серверний маршрут, який фільтрує рядки за пошуком без урахування регістру в кількох стовпцях. Для невеликого списку, який уже завантажено в браузер, фільтрація в браузері ще простіша.
Чи потрібні мені Algolia або Elasticsearch для пошуку?
Зазвичай на початку ні. Повнотекстовий пошук у Postgres добре справляється зі збігом слів, ранжуванням і тисячами-мільйонами рядків. Хостований пошуковий сервіс варто впроваджувати, коли потрібна висока терпимість до помилок у словах, миттєві результати під час набору на великих даних або тонке налаштування релевантності.
Чому мій пошук не знаходить результати, якщо є помилки в словах?
Базовий збіг і стандартний повнотекстовий пошук шукають слова так, як їх введено (або їхні основи), тож помилка в слові призводить до промаху. Потрібен нечіткий збіг, наприклад схожість за триграмами в Postgres або пошуковий сервіс із терпимістю до помилок.
Пошук має працювати в браузері чи на сервері?
На сервері для всього, що виходить за межі невеликого публічного списку. Пошук на сервері масштабується, враховує дозволи та не надсилає весь ваш набір даних кожному відвідувачу.