Введение
На часах было почти 3 часа дня, я хотел было сделать себе послеобеденный кофе, но получил новое задание от тимлида. Необходимо было сделать поиск для онлайн платформы просмотра ТВ, сериалов и фильмов.
Старт
Я приступил к выполнению задачи. Запросы в гугле были разного уровня: от “зачем нужен поиск”, до “имплементация обратного индекса в СУБД”. Вот что удалось найти:
- “Серьезные пацаны” используют для поиска всякие Sphinx и ElasticSearch. Минусы: их нужно настраивать, загонять в них данные и мониторить их потребности.
- Haystack обеспечивает модульный поиск Django. У него простой и понятный API для работы над поиском, который позволяет подключать различные поисковые движки. Однако выявилась проблема в настройке минимального количества символов в системе серча: при значении — 1 он переставал корректно работать.
- Любая современная база данных имеет в себе встроенный полнотекстовый поиск.
После прочтения “кучи” статей о настройках поиска в хорошем виде в django, я остановился на PostgreSql, так как у “постгреса” часто появляются новые “плюшки”.
Подготовка окружения
Установка и настройка PostgreSql и Django настолько простая в нашем случае, что вы можете ее сделать по гайду. Также прочтите немного теории.
Индексирование в Django проекте
Индексирование бывает прямым и обратным. Например, если с помощью индексирования мы узнаём, что в левой части супермаркета есть баклажаны, картофель, помидоры и мармелад; в правой — мороженое, сухофрукты, мармелад и хлеб, то это прямой индекс.
Но что если нам нужно найти места, где есть мармелад? Придется пробегать циклом по всем местам и выбирать те, в которых имеется неободимый продукт.
Есть и другое решение. Продолжив читать книгу “Поиск. Индексы. И так далее” мы увидим, что нам может помочь обратный индекс. Он работает противоположно прямому, и после применения можно увидеть такую структуру:
Помидоры — левая сторона, при входе
Картофель — конец, левая сторона
Мармелад — левая сторона, правая сторона
Теперь мы точно знаем, где есть наш мармелад!
Возникает новый вопрос, как безболезненно внедрить эту “фичу” в наш Django проект?
Нашел решение. Благодаря разработчикам “постгреса”, сегодня есть простой в использовании GIN, который работает на основе обратного индекса.
Для использования его в “джанге” нужно всего лишь поставить psycorg и импортировать необходимые зависимости.
Тем самым мы проиндексировали поле title. Теперь давайте посмотрим, создался ли индекс внутри базы данных. Проверить можно командой:
Мы видим, что буквально с помощью одной строки кода мы упростили жизнь. И так, у нас есть проиндексированные данные, но как с ними работать? Будет ли работать ‘__icontains’, если просто указать необходимое поле в запросе?
Ответ: Да
Давайте разберем детально, почему.
Работа с запросами
Выше мы уже определили модель Movies, давайте продолжим работать с ней же.
Посмотрите, как выглядит обычный запрос Django ORM и Sql.
Django
Sql
Вывод
Чтобы выполнить более сложный запрос, мы должны использовать три новых класса: SearchVector, SearchQuery, SearchRank.
SearchVector
Можно использовать SearchVector для создания нашего запроса с использованием нескольких полей. Затем использовать <filter>.
Django
Вывод
Так мы нашли фильмы “Wilson” и “The Pursuit of Happiness”. В первом случае, слово “Wilson” содержится в названии, во втором, в описании картины (слово “Wilson” в описании ленты добавил лично, потому что было лень искать слово, которое будет удовлетворять запросу).
SearchQuery
Бывает и такое, когда нужно сделать поиск по нескольким словам в базе данных. Представьте, вы ищете фильм в описании которого содержится фраза “good life”. SearchQuery позволит задать порядок этих слов в описании.
Django
Sql
Вывод:
SearchRank
Думаю, лучшее в данной статье — это SearchRank, так как он дает возможность посмотреть, насколько каждый элемент удовлетворяет запросу.
Только представьте, что вы хотите найти фильм, но не помните его названия. Все что вы помните — это то, что в названии были слова “Girl” и “Tattoo”. Могу Вас обрадовать SearchRank отлично справится с задачей: найдёт и отсортирует по степени “схожести” результат.
Django
Sql
Вывод
Заключение
Люди пользуются поиском везде, поэтому он неотъемлемая часть большинства проектов. Поиск, который я реализовал, внедрен на сайт, где количество фильмов и сериалов превышает несколько тысяч.
Более того, при тщательной настройке PostgreSql с Django можно получить реактивный поиск. Надеюсь, что после прочтения статьи вы захотите поработать с Postgresql.
Ранее статья была опубликована тут.