색인화

모델을 검색 가능하게 하려면 검색 색인에 추가해야 합니다. 모든 페이지, 이미지 및 문서는 자동으로 색인화되므로 즉시 검색할 수 있습니다.

Page 또는 Image 의 서브클래스에 추가 필드를 생성한 경우 이러한 새 필드를 검색 색인에도 추가하여 사용자의 검색어가 콘텐츠와 일치하도록 할 수 있습니다. 이에 대한 정보는 추가 필드 색인화 를 참조하십시오.

검색 가능하게 만들고 싶은 사용자 지정 모델이 있는 경우 사용자 지정 모델 색인화 를 참조하십시오.

색인 업데이트

검색 색인이 데이터베이스와 분리되어 있는 경우(예: Elasticsearch를 사용하는 경우) 둘 다 동기화 상태로 유지해야 합니다. 이를 수행하는 두 가지 방법이 있습니다. 검색 시그널 핸들러를 사용하거나 update_index 명령을 주기적으로 호출하는 것입니다. 최상의 속도와 안정성을 위해 가능하면 둘 다 사용하는 것이 좋습니다.

시그널 핸들러

wagtailsearch 는 모든 색인화된 모델의 저장/삭제 시그널에 바인딩되는 일부 시그널 핸들러를 제공합니다. 이렇게 하면 WAGTAILSEARCH_BACKENDS 에 등록한 모든 백엔드에서 자동으로 추가 및 삭제됩니다. 이러한 시그널 핸들러는 wagtail.search 앱이 로드될 때 자동으로 등록됩니다.

경우에 따라 콘텐츠가 자동으로 다시 색인화되는 것을 원하지 않고 대신 색인화를 위해 update_index 명령에 의존할 수 있습니다. 이러한 시그널 핸들러를 비활성화해야 하는 경우 다음 방법 중 하나를 사용하십시오.

모델에 대한 자동 업데이트 시그널 핸들러 비활성화

모델 클래스에 search_auto_update = False 를 속성으로 추가하여 개별 모델에 대한 시그널 핸들러를 비활성화할 수 있습니다.

검색 백엔드/전체 사이트에 대한 자동 업데이트 시그널 핸들러 비활성화

백엔드의 AUTO_UPDATE 설정을 False 로 설정하여 전체 검색 백엔드에 대한 시그널 핸들러를 비활성화할 수 있습니다.

모든 검색 백엔드에 AUTO_UPDATEFalse 로 설정된 경우 시그널 핸들러는 전체 사이트에 대해 완전히 비활성화됩니다.

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 = [] 를 설정하여 모델의 색인화를 완전히 비활성화할 수 있습니다. 이렇게 하면 시그널 핸들러 및 update_index 관리 명령에 의한 색인 업데이트가 비활성화됩니다.

추가 필드 색인화

필드는 Page 파생 모델의 search_fields 속성에 명시적으로 추가되어야 검색/필터링할 수 있습니다. 이는 search_fields 를 재정의하여 추가 SearchField/FilterField 객체 목록을 추가하여 수행됩니다.

예시

이것은 descriptiondate 의 두 필드를 가진 EventPage 모델을 만듭니다. descriptionSearchField 로 색인화되고 dateFilterField 로 색인화됩니다.

from wagtail.search import index
from django.utils import timezone

class EventPage(Page):
    description = models.TextField()
    date = models.DateField()

    search_fields = Page.search_fields + [ # Page에서 search_fields 상속
        index.SearchField('description'),
        index.FilterField('date'),
    ]


# 제목 또는 설명에 "Christmas" 문자열이 포함된 미래 이벤트 가져오기
>>> EventPage.objects.filter(date__gt=timezone.now()).search("Christmas")

index.SearchField

이것들은 모델에 대한 전체 텍스트 검색을 수행하는 데 사용되며, 일반적으로 텍스트 필드에 사용됩니다.

옵션

  • boost (int/float) - 필드를 다른 필드보다 더 중요하게 설정할 수 있습니다. 필드에 높은 숫자를 설정하면 해당 필드에 일치하는 페이지가 더 높은 순위로 지정됩니다. 기본적으로 페이지 제목 필드에는 2로, 다른 모든 필드에는 1로 설정됩니다.

    참고

    PostgresSQL 전체 텍스트 검색은 네 가지 가중치 수준(A, B, C, D)만 지원합니다. 데이터베이스 검색 백엔드 wagtail.search.backends.database 가 PostgreSQL 데이터베이스에서 사용될 때, 프로젝트의 모든 부스트 값을 고려하여 네 가지 사용 가능한 가중치로 그룹화합니다.

    이는 이 구성에서 더 많은 부스트 값이 사용되었더라도 검색 결과 순위를 매기는 데 효과적으로 네 가지 부스트 수준만 사용된다는 것을 의미합니다.

    ./manage.py shell 로 새 Django 셸을 시작하고 wagtail.search.backends.database.postgres.weights.BOOST_WEIGHTS 를 검사하여 어떤 부스트 임계값이 PostgreSQL에서 어떤 가중치에 매핑되는지 대략적으로 알 수 있습니다. [(10.0, 'A'), (7.166666666666666, 'B'), (4.333333333333333, 'C'), (1.5, 'D')] 와 같은 것을 볼 수 있습니다. 각 임계값 위의 부스트 값은 해당 가중치로 처리됩니다.

  • es_extra (dict) - 이 필드는 개발자가 Elasticsearch 매핑에서 필드에 대한 설정을 설정하거나 재정의할 수 있도록 합니다. Wagtail에서 아직 지원되지 않는 Elasticsearch 기능을 사용하려면 이 기능을 사용하십시오.

index.AutocompleteField

이것들은 부분 단어와 일치하는 자동 완성 쿼리에 사용됩니다. 예를 들어, Hello World! 라는 제목의 페이지는 사용자가 검색 상자에 Hel 만 입력해도 찾아집니다.

이것은 index.SearchField 와 동일한 옵션을 사용합니다.

참고

index.AutocompleteField 는 검색 결과에 표시되는 필드에만 사용해야 합니다. 이렇게 하면 사용자가 부분적으로 일치하는 단어를 볼 수 있습니다.

index.FilterField

이것들은 검색 색인에 추가되지만 전체 텍스트 검색에는 사용되지 않습니다. 대신 검색 결과에 필터를 실행할 수 있도록 합니다.

index.RelatedFields

이것은 관련 객체의 필드를 색인화할 수 있도록 합니다. 역 접근자를 포함하여 모든 유형의 관련 필드에서 작동합니다.

예를 들어, 저자에 대한 ForeignKey 가 있는 책이 있는 경우 저자의 name 필드를 책 안에 중첩할 수 있습니다.

from wagtail.search import index

class Book(models.Model, index.Indexed):
    ...

    search_fields = [
        index.SearchField('title'),
        index.FilterField('published_date'),

        index.RelatedFields('author', [
            index.SearchField('name'),
        ]),
    ]

이렇게 하면 저자의 이름으로 책을 검색할 수 있습니다.

반대 방향으로도 작동합니다. 저자의 책을 색인화하여 저자가 게시한 책의 제목으로 검색할 수 있습니다.

from wagtail.search import index

class Author(models.Model, index.Indexed):
    ...

    search_fields = [
        index.SearchField('name'),
        index.FilterField('date_of_birth'),

        index.RelatedFields('books', [
            index.SearchField('title'),
        ]),
    ]

index.RelatedFields 에 필터링

QuerySet API를 사용하여 index.RelatedFields 내의 index.FilterFields 를 필터링하는 것은 불가능합니다. index.RelatedFields 내에 index.FilterField 를 배치하는 것은 유효하며, 색인화 시 적절한 필드 데이터가 저장되지만, QuerySet API는 현재 관계를 포괄하는 필터를 지원하지 않으므로 이러한 필드에 액세스할 방법이 없습니다. 그러나 Elasticsearch를 수동으로 쿼리하여 사용할 수 있어야 합니다.

QuerySet API를 사용하여 index.RelatedFields 에 필터링하는 것은 Wagtail의 향후 릴리스에서 계획되어 있습니다.

호출 가능 및 기타 속성 색인화

검색/필터 필드는 Django 모델 필드일 필요가 없습니다. 모델 클래스의 모든 메서드 또는 속성일 수도 있습니다.

이것의 한 가지 용도는 Django가 선택 항목이 있는 필드에 대해 자동으로 생성하는 get_*_display 메서드를 색인화하는 것입니다.

from wagtail.search import index

class EventPage(Page):
    IS_PRIVATE_CHOICES = (
        (False, "공개"),
        (True, "비공개"),
    )

    is_private = models.BooleanField(choices=IS_PRIVATE_CHOICES)

    search_fields = Page.search_fields + [
        # 검색을 위해 사람이 읽을 수 있는 문자열을 색인화합니다.
        index.SearchField('get_is_private_display'),

        # 필터링을 위해 부울 값을 색인화합니다.
        index.FilterField('is_private'),
    ]

호출 가능 객체는 관련 모델의 필드를 색인화하는 방법도 제공합니다. InlinePanel 의 예시에서 각 BookPage를 관련 링크의 제목으로 색인화하려면:

class BookPage(Page):
    # ...
    def get_related_link_titles(self):
        # 제목 목록을 가져와 연결합니다.
        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', boost=10),
        index.AutocompleteField('title', boost=10),
        index.SearchField('get_genre_display'),

        index.FilterField('genre'),
        index.FilterField('author'),
        index.FilterField('published_date'),
    ]

# 이 모델에는 QuerySet에 검색 메서드가 없으므로 백엔드에서 직접 검색을 호출해야 합니다.
>>> from wagtail.search.backends import get_search_backend
>>> s = get_search_backend()

# 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>]