Spec-Zone.ru › Django 5.2

Поиск

Обычная задача веб-приложений — поиск данных в базе данных по вводу пользователя. В простом случае это может быть фильтрация списка объектов по категории. Более сложный случай может потребовать поиска с весами, категоризацией, выделением, несколькими языками и так далее. Этот документ описывает некоторые возможные варианты использования и инструменты, которые вы можете использовать.

Мы будем ссылаться на те же модели, что и в составлении запросов.

Варианты использования

Стандартные текстовые запросы

Текстовые поля имеют набор операций сопоставления. Например, вы можете разрешить поиск автора следующим образом:

>>> Author.objects.filter(name__contains="Terry")
[<Author: Terry Gilliam>, <Author: Terry Jones>]

Это очень хрупкое решение, так как оно требует, чтобы пользователь знал точную подстроку имени автора. Лучший подход — это нечувствительное к регистру сопоставление (icontains), но это лишь незначительно лучше.

Более продвинутые функции сравнения базы данных

Если вы используете PostgreSQL, Django предоставляет набор инструментов, специфичных для базы данных, чтобы позволить вам использовать более сложные варианты запросов. Другие базы данных имеют разные наборы инструментов, возможно, через плагины или пользовательские функции. Django в настоящее время не включает поддержку для них. Мы будем использовать примеры из PostgreSQL, чтобы продемонстрировать тип функциональности, которая может быть у баз данных.

Поиск в других базах данных

Все инструменты поиска, предоставляемые django.contrib.postgres, построены полностью на общедоступных API, таких как пользовательские сопоставления и функции базы данных. В зависимости от вашей базы данных вы должны иметь возможность создавать запросы, чтобы разрешить аналогичные API. Если есть конкретные вещи, которые нельзя сделать таким образом, пожалуйста, откройте тикет.

В приведенном выше примере мы определили, что поиск без учета регистра будет более полезным. При работе с именами, не являющимися английскими, дополнительное улучшение — использовать unaccented comparison:

>>> Author.objects.filter(name__unaccent__icontains="Helen")
[<Author: Helen Mirren>, <Author: Helena Bonham Carter>, <Author: Hélène Joy>]

Это демонстрирует другую проблему, где мы подбираем варианты написания имени. В данном случае у нас есть асимметрия — поиск Helen найдет Helena или Hélène, но не наоборот. Другой вариант — использовать сравнение trigram_similar, которое сравнивает последовательности букв.

Например:

>>> Author.objects.filter(name__unaccent__lower__trigram_similar="Hélène")
[<Author: Helen Mirren>, <Author: Hélène Joy>]

Теперь у нас другая проблема — более длинное имя «Елена Бонем Картер» не отображается, поскольку оно намного длиннее. Поиск триграмм рассматривает все сочетания из трех букв и сравнивает, сколько из них встречается как в поисковом запросе, так и в исходной строке. Для более длинного имени существует больше сочетаний, которые не встречаются в исходной строке, поэтому оно больше не считается близким совпадением.

Правильный выбор функций сравнения здесь зависит от вашего конкретного набора данных, например, от используемого языка (языков) и типа искомого текста. Все примеры, которые мы видели, относятся к коротким строкам, где пользователь, вероятно, введет что-то близкое (по различным определениям) к исходным данным.

Поиск по документам

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

  • Игнорирование «стоп-слов», таких как «а», «the», «и».
  • Сведение слов к основам, так что «лошадь» и «лошади» считаются похожими.
  • Весование слов на основе различных критериев, таких как частота их появления в тексте или важность полей, например, заголовков или ключевых слов, в которых они появляются.

Существует множество альтернатив для использования поискового программного обеспечения, некоторые из наиболее заметных — Elastic и Solr. Это полнофункциональные решения для поиска по документам. Чтобы использовать их с данными из моделей Django, вам потребуется уровень, который преобразует ваши данные в текстовый документ, включая обратные ссылки на идентификаторы базы данных. Когда поиск с помощью движка возвращает определенный документ, вы можете затем найти его в базе данных. Существует множество сторонних библиотек, которые предназначены для помощи в этом процессе.

Поддержка PostgreSQL

PostgreSQL имеет собственное встроенное реализацию полнотекстового поиска. Хотя он не такой мощный, как некоторые другие поисковые системы, его преимущество состоит в том, что он находится внутри вашей базы данных, поэтому его можно легко комбинировать с другими реляционными запросами, такими как категоризация.

Модуль django.contrib.postgres предоставляет некоторые вспомогательные средства для создания этих запросов. Например, запрос может выбрать все записи блога, в которых упоминается «сыр»:

>>> Entry.objects.filter(body_text__search="cheese")
[<Entry: Cheese on Toast recipes>, <Entry: Pizza recipes>]

Вы также можете фильтровать по комбинации полей и связанных моделей:

>>> Entry.objects.annotate(
...     search=SearchVector("blog__tagline", "body_text"),
... ).filter(search="cheese")
[
    <Entry: Cheese on Toast recipes>,
    <Entry: Pizza Recipes>,
    <Entry: Dairy farming in Argentina>,
]

См. документ contrib.postgres Полнотекстовый поиск для получения подробной информации.

© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/5.2/topics/db/search/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API