Spec-Zone.ru › Django 1.11

Полнотекстовый поиск

Новое в Django 1.10.

Функции базы данных в модуле django.contrib.postgres.search облегчают использование полнотекстового поискового движка PostgreSQL полнотекстовый поиск.

В примерах этого документа мы будем использовать модели, определённые в создании запросов.

См. также

Для общего обзора поиска см. документацию по теме.

Поиск search

Самый простой способ использования полнотекстового поиска — поиск одного термина по одному столбцу в базе данных. Например:

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

Это создаёт to_tsvector в базе данных из поля body_text и plainto_tsquery из поискового запроса 'Cheese', оба с использованием стандартной конфигурации поиска базы данных. Результаты получаются путём сопоставления запроса и вектора.

Чтобы использовать поиск search , 'django.contrib.postgres' должен быть в вашем INSTALLED_APPS.

SearchVector

class SearchVector(*expressions, config=None, weight=None) [source]

Поиск по одному полю — это здорово, но довольно ограниченно. Экземпляры Entry , по которым мы ищем, принадлежат Blog, которое имеет поле tagline. Для запроса по обоим полям используйте SearchVector:

>>> from django.contrib.postgres.search import SearchVector
>>> Entry.objects.annotate(
...     search=SearchVector('body_text', 'blog__tagline'),
... ).filter(search='Cheese')
[<Entry: Cheese on Toast recipes>, <Entry: Pizza Recipes>]

Аргументы для SearchVector могут быть любым Expression или именем поля. Несколько аргументов будут объединены вместе с пробелом, чтобы поисковый документ включал их все.

SearchVector объекты могут быть объединены вместе, что позволяет их повторно использовать. Например:

>>> Entry.objects.annotate(
...     search=SearchVector('body_text') + SearchVector('blog__tagline'),
... ).filter(search='Cheese')
[<Entry: Cheese on Toast recipes>, <Entry: Pizza Recipes>]

См. Изменение конфигурации поиска и Определение весов запросов для объяснения параметров config и weight.

SearchQuery

class SearchQuery(value, config=None) [source]

SearchQuery преобразует предоставленные пользователем термины в объект запроса поиска, который база данных сравнивает с вектором поиска. По умолчанию все слова, предоставленные пользователем, проходят через алгоритмы стеминга, а затем ищет соответствия для всех полученных терминов.

SearchQuery термины могут быть объединены логически, чтобы обеспечить большую гибкость:

>>> from django.contrib.postgres.search import SearchQuery
>>> SearchQuery('potato') & SearchQuery('ireland')  # potato AND ireland
>>> SearchQuery('potato') | SearchQuery('penguin')  # potato OR penguin
>>> ~SearchQuery('sausage')  # NOT sausage

См. Изменение конфигурации поиска для объяснения параметра config.

SearchRank

class SearchRank(vector, query, weights=None) [source]

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

>>> from django.contrib.postgres.search import SearchQuery, SearchRank, SearchVector
>>> vector = SearchVector('body_text')
>>> query = SearchQuery('cheese')
>>> Entry.objects.annotate(rank=SearchRank(vector, query)).order_by('-rank')
[<Entry: Cheese on Toast recipes>, <Entry: Pizza recipes>]

См. Определение весов запросов для объяснения параметра weights.

Изменение конфигурации поиска

Вы можете указать атрибут config для SearchVector и SearchQuery для использования другой конфигурации поиска. Это позволяет использовать различные парсеры и словари языков, как определено в базе данных:

>>> from django.contrib.postgres.search import SearchQuery, SearchVector
>>> Entry.objects.annotate(
...     search=SearchVector('body_text', config='french'),
... ).filter(search=SearchQuery('œuf', config='french'))
[<Entry: Pain perdu>]

Значение config также можно хранить в другом столбце:

>>> from django.db.models import F
>>> Entry.objects.annotate(
...     search=SearchVector('body_text', config=F('blog__language')),
... ).filter(search=SearchQuery('œuf', config=F('blog__language')))
[<Entry: Pain perdu>]

Определение весов запросов

У каждого поля может быть разная релевантность в запросе, поэтому можно установить веса различных векторов перед их объединением:

>>> from django.contrib.postgres.search import SearchQuery, SearchRank, SearchVector
>>> vector = SearchVector('body_text', weight='A') + SearchVector('blog__tagline', weight='B')
>>> query = SearchQuery('cheese')
>>> Entry.objects.annotate(rank=SearchRank(vector, query)).filter(rank__gte=0.3).order_by('rank')

Вес должен быть одной из следующих букв: D, C, B, A. По умолчанию эти веса относятся к числам 0.1, 0.2, 0.4, и 1.0, соответственно. Если вы хотите присвоить им разные веса, передайте список из четырёх чисел с плавающей точкой в SearchRank как weights в том же порядке:

>>> rank = SearchRank(vector, query, weights=[0.2, 0.4, 0.6, 0.8])
>>> Entry.objects.annotate(rank=rank).filter(rank__gte=0.3).order_by('-rank')

Производительность

Специальная конфигурация базы данных не требуется для использования этих функций, однако, если вы ищете более чем несколько сотен записей, вам, вероятно, придётся столкнуться с проблемами производительности. Полнотекстовый поиск — более интенсивный процесс, чем, например, сравнение размера целого числа.

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

SearchVectorField

class SearchVectorField [source]

Если этот подход окажется слишком медленным, вы можете добавить SearchVectorField в свою модель. Вам нужно будет поддерживать его заполнение триггерами, например, как описано в документации PostgreSQL. Затем вы можете запросить поле, как если бы это был анотированный SearchVector:

>>> Entry.objects.update(search_vector=SearchVector('body_text'))
>>> Entry.objects.filter(search_vector='cheese')
[<Entry: Cheese on Toast recipes>, <Entry: Pizza recipes>]

Подобие триграмм

Ещё один подход к поиску — подобие триграмм. Триграмма — это группа из трёх последовательных символов. В дополнение к trigram_similar поиску, вы можете использовать несколько других выражений.

Для их использования вам необходимо активировать расширение pg_trgm в PostgreSQL. Вы можете установить его с помощью операции миграции TrigramExtension.

TrigramSimilarity

class TrigramSimilarity(expression, string, **extra) [source]
Новое в Django 1.10.

Принимает имя поля или выражение и строку или выражение. Возвращает подобие триграмм между двумя аргументами.

Пример использования:

>>> from django.contrib.postgres.search import TrigramSimilarity
>>> Author.objects.create(name='Katy Stevens')
>>> Author.objects.create(name='Stephen Keats')
>>> test = 'Katie Stephens'
>>> Author.objects.annotate(
...     similarity=TrigramSimilarity('name', test),
... ).filter(similarity__gt=0.3).order_by('-similarity')
[<Author: Katy Stevens>, <Author: Stephen Keats>]

TrigramDistance

class TrigramDistance(expression, string, **extra) [source]
Новое в Django 1.10.

Принимает имя поля или выражение и строку или выражение. Возвращает расстояние триграмм между двумя аргументами.

Пример использования:

>>> from django.contrib.postgres.search import TrigramDistance
>>> Author.objects.create(name='Katy Stevens')
>>> Author.objects.create(name='Stephen Keats')
>>> test = 'Katie Stephens'
>>> Author.objects.annotate(
...     distance=TrigramDistance('name', test),
... ).filter(distance__lte=0.7).order_by('distance')
[<Author: Katy Stevens>, <Author: Stephen Keats>]

© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/1.11/ref/contrib/postgres/search/

Spec-Zone.ru

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