Индексирование
Чтобы сделать модель подлежащей поиску, необходимо добавить её в индекс поиска. Все страницы, изображения и документы индексируются для вас, поэтому вы можете сразу начать их поиск.
Если вы создали дополнительные поля в подклассе Page или Image, вы можете добавить эти новые поля в индекс поиска, чтобы запросы пользователей соответствовали их содержимому. См. Индексирование дополнительных полей для получения информации о том, как это сделать.
Если у вас есть пользовательская модель, которую вы хотите сделать подлежащей поиску, см. Индексирование пользовательских моделей.
Обновление индекса
Если индекс поиска хранится отдельно от базы данных (например, при использовании Elasticsearch), необходимо поддерживать их синхронизацию. Есть два способа сделать это: использование обработчиков сигналов поиска или периодическое вызов команды update_index. Для наилучшей скорости и надёжности рекомендуется использовать оба способа, если это возможно.
Обработчики сигналов
wagtailsearch предоставляет некоторые обработчики сигналов, которые привязываются к сигналам сохранения/удаления всех индексируемых моделей. Это автоматически добавит и удалит их из всех зарегистрированных вами бэкэндов в WAGTAILSEARCH_BACKENDS. Эти обработчики сигналов автоматически регистрируются при загрузке приложения wagtail.search.
В некоторых случаях вы можете не захотеть, чтобы ваше содержимое автоматически переиндексировалось, и вместо этого полагаться на команду update_index для индексирования. Если вам нужно отключить эти обработчики сигналов, используйте один из следующих методов:
Отключение автоматического обновления обработчиков сигналов для модели
Вы можете отключить обработчики сигналов для отдельной модели, добавив search_auto_update = False в качестве атрибута в классе модели.
Отключение автоматического обновления обработчиков сигналов для бэкэнда поиска/всего сайта
Вы можете отключить обработчики сигналов для всего бэкэнда поиска, установив параметр AUTO_UPDATE бэкэнда в значение False.
Если для всех бэкэндов поиска параметр AUTO_UPDATE установлен в значение False, обработчики сигналов будут полностью отключены для всего сайта.
Для документации параметра AUTO_UPDATE см. AUTO_UPDATE.
Команда update_index
Wagtail также предоставляет команду для перестроения индекса с нуля.
./manage.py update_index
Рекомендуется запускать эту команду один раз в неделю и в следующие моменты:
- в любое время, когда страницы были созданы через скрипт (например, после импорта)
- всякий раз, когда были внесены изменения в модели или конфигурацию поиска
Во время выполнения этой команды поиск может не возвращать результаты, поэтому избегайте запуска в пиковые часы.
Примечание
Команда update_index также имеет псевдоним wagtail_update_index, для использования, когда другое установленное приложение (например, Haystack) предоставляет конфликтную команду update_index. В этом случае запись другого пакета в INSTALLED_APPS должна располагаться выше wagtail.search, чтобы его команда update_index имела приоритет над командой Wagtail.
Индексирование дополнительных полей
Поля должны быть явно добавлены в свойство search_fields вашей модели, производной от Page, чтобы вы могли выполнять поиск/фильтрацию по ним. Это делается путём переопределения search_fields для добавления списка дополнительных объектов SearchField/FilterField.
Пример
Это создаёт модель EventPage с двумя полями: description и date. description индексируется как SearchField, а date — как FilterField.
from wagtail.search import index
from django.utils import timezone
class EventPage(Page):
description = models.TextField()
date = models.DateField()
search_fields = Page.search_fields + [ # Inherit search_fields from Page
index.SearchField('description'),
index.FilterField('date'),
]
# Get future events which contain the string "Christmas" in the title or description
>>> EventPage.objects.filter(date__gt=timezone.now()).search("Christmas")
index.SearchField
Они используются для выполнения полнотекстового поиска по вашим моделям, обычно для текстовых полей.
Параметры
-
partial_match (
boolean) - Установка этого значения в true позволяет соответствовать результатам по частям слов. Например, это установлено по умолчанию для поля title, поэтому страница с названиемHello World!будет найдена, если пользователь введёт толькоHelв поле поиска. -
boost (
int/float) - Это позволяет устанавливать поля как более важные, чем другие. Установка большого значения для поля приведет к тому, что страницы с совпадениями в этом поле будут ранжироваться выше. По умолчанию это установлено в 2 для поля заголовка страницы и в 1 для всех остальных полей.Примечание
Полнотекстовый поиск PostgresSQL поддерживает только четыре уровня весов (A, B, C, D). Когда используется бэкэнд базы данных поиска
wagtail.search.backends.databaseв базе данных PostgreSQL, он будет учитывать все значения boost в проекте и группировать их в четыре доступных весовых класса.Это означает, что в этой конфигурации используются только четыре уровня boost для ранжирования результатов поиска, даже если было использовано больше значений boost.
Чтобы примерно определить, какие пороговые значения boost соответствуют какому весу в PostgresSQL, запустите новый Django shell с помощью
./manage.py shellи проверьтеwagtail.search.backends.database.postgres.weights.BOOST_WEIGHTS. Вы должны увидеть что-то вроде[(10.0, 'A'), (7.166666666666666, 'B'), (4.333333333333333, 'C'), (1.5, 'D')]. Значения boost, превышающие каждый порог, будут обрабатываться с соответствующим весом. -
es_extra (
dict) - Это поле позволяет разработчику устанавливать или переопределять любой параметр поля в соответствии с картой Elasticsearch. Используйте его, если вы хотите использовать возможности Elasticsearch, которые ещё не поддерживаются в Wagtail.
index.AutocompleteField
Они используются для запросов автозаполнения, которые соответствуют частям слов. Например, страница с названием Hello World! будет найдена, если пользователь введёт только Hel в поле поиска.
Это принимает те же самые параметры, что и index.SearchField (за исключением partial_match, который не имеет эффекта).
Примечание
Индексируйте только те поля, которые отображаются в результатах поиска с index.AutocompleteField. Это позволяет пользователям видеть любые слова, которые были частично сопоставлены.
index.FilterField
Они добавляются в индекс поиска, но не используются для полнотекстового поиска. Вместо этого они позволяют вам применять фильтры к результатам поиска.
Индексирование вызываемых функций и других атрибутов
Поля поиска/фильтра не обязательно должны быть полями модели Django. Они также могут быть любым методом или атрибутом вашего класса модели.
Одно из применений этого — индексирование методов get_*_display Django создаёт автоматически для полей с набором вариантов.
from wagtail.search import index
class EventPage(Page):
IS_PRIVATE_CHOICES = (
(False, "Public"),
(True, "Private"),
)
is_private = models.BooleanField(choices=IS_PRIVATE_CHOICES)
search_fields = Page.search_fields + [
# Index the human-readable string for searching.
index.SearchField('get_is_private_display'),
# Index the boolean value for filtering.
index.FilterField('is_private'),
]
Вызываемые функции также предоставляют способ индексирования полей из связанных моделей. В примере из Inline Panels and Model Clusters для индексации каждой BookPage по названиям её related_links:
class BookPage(Page):
# ...
def get_related_link_titles(self):
# Get list of titles and concatenate them
return '\n'.join(self.related_links.all().values_list('name', flat=True))
search_fields = Page.search_fields + [
# ...
index.SearchField('get_related_link_titles'),
]
Индексирование пользовательских моделей
Любая модель Django может быть индексирована и по ней можно искать.
Для этого унаследуйте от index.Indexed и добавьте некоторые search_fields в модель.
from wagtail.search import index
class Book(index.Indexed, models.Model):
title = models.CharField(max_length=255)
genre = models.CharField(max_length=255, choices=GENRE_CHOICES)
author = models.ForeignKey(Author, on_delete=models.CASCADE)
published_date = models.DateTimeField()
search_fields = [
index.SearchField('title', partial_match=True, boost=10),
index.SearchField('get_genre_display'),
index.FilterField('genre'),
index.FilterField('author'),
index.FilterField('published_date'),
]
# As this model doesn't have a search method in its QuerySet, we have to call search directly on the backend
>>> from wagtail.search.backends import get_search_backend
>>> s = get_search_backend()
# Run a search for a book by Roald Dahl
>>> roald_dahl = Author.objects.get(name="Roald Dahl")
>>> s.search("chocolate factory", Book.objects.filter(author=roald_dahl))
[<Book: Charlie and the chocolate factory>]
© 2014-present Torchbox Ltd and individual contributors.
All rights are reserved.
Licensed under the BSD License.
https://docs.wagtail.org/en/stable/topics/search/indexing.html