Djangoで検索結果を絞り込む:Haystackを使った属性検索


Simple full-text search

これは、最もシンプルで使いやすい検索方法です。全文検索エンジンである Haystack を利用し、モデル内の全てのフィールドを対象に検索を行います。

実装手順

  1. HaystackWhoosh をインストールします。
pip install haystack whoosh
  1. settings.py ファイルに以下の設定を追加します。
HAYSTACK_CONNECTIONS = {
    'default': {
        'ENGINE': 'haystack.backends.whoosh_backend.WhooshEngine',
        'STORAGE': 'haystack.storage.filesystem.FileSystemStorage',
        'PATH': os.path.join(BASE_DIR, 'indexes'),
    },
}
  1. 検索対象となるモデルを登録します。
from haystack import indexes

class MyModelIndex(indexes.SearchIndex, indexes.Indexable):
    text = indexes.CharField(document=True, use_template=True)

    def get_model(self):
        return MyModel

    def index_queryset(self, using=None):
        self.index_queryset(MyModel.objects.all(), using=using)
  1. コマンドを実行して全文インデックスを作成します。
python manage.py haystack rebuild
  1. 検索ビューを作成します。
from django.shortcuts import render

from haystack.views import SearchView

class MySearchView(SearchView):
    template_name = 'search/results.html'

    def search(self, request):
        # 検索クエリを取得
        query = request.GET.get('q')

        # 検索を実行
        results = super().search(query)

        # 検索結果をコンテキストに格納
        context = {
            'results': results,
        }

        # 検索結果テンプレートをレンダリング
        return render(request, self.template_name, context)

Faceted search

これは、より高度な検索機能を実装したい場合に役立つ方法です。カテゴリーやタグなどの属性に基づいて絞り込み検索を行うことができます。

実装手順

  1. Simple full-text search と同様に、HaystackWhoosh をインストールして設定を行います。

  2. 検索対象となるモデルを登録します。

from haystack import indexes

class MyModelIndex(indexes.SearchIndex, indexes.Indexable):
    text = indexes.CharField(document=True, use_template=True)

    # カテゴリーやタグなどの属性フィールドを追加
    category = indexes.CharField(index_facet=True)
    tag = indexes.CharField(index_facet=True)

    def get_model(self):
        return MyModel

    def index_queryset(self, using=None):
        self.index_queryset(MyModel.objects.all(), using=using)
  1. コマンドを実行して全文インデックスを作成します。
python manage.py haystack rebuild
  1. 検索ビューを作成します。
from django.shortcuts import render

from haystack.views import FacetedSearchView

class MyFacetedSearchView(FacetedSearchView):
    template_name = 'search/results.html'

    def search(self, request):
        # 検索クエリを取得
        query = request.GET.get('q')

        # 検索を実行
        results = super().search(query)

        # 検索結果とファセット情報をコンテキストに格納
        context = {
            'results': results,
            'facets': self.get_facets(),
        }

        # 検索結果テンプレートをレンダリング
        return render(request, self.template_name, context)

上記の2つの方法は、それぞれ異なるメリットとデメリットがあります。

  • Faceted search

    • メリット:高度な検索機能が利用できる
    • デメリット:実装が複雑
    • メリット:実装が簡単
    • デメリット:高度な検索機能が利用できない

ご自身のニーズに合わせて、適切な方法を選択してください。

  • [Haystack documentation](https://haystack.readthedocs


Simple full-text search

# settings.py

HAYSTACK_CONNECTIONS = {
    'default': {
        'ENGINE': 'haystack.backends.whoosh_backend.WhooshEngine',
        'STORAGE': 'haystack.storage.filesystem.FileSystemStorage',
        'PATH': os.path.join(BASE_DIR, 'indexes'),
    },
}

# models.py

from haystack import indexes

class MyModelIndex(indexes.SearchIndex, indexes.Indexable):
    text = indexes.CharField(document=True, use_template=True)

    def get_model(self):
        return MyModel

    def index_queryset(self, using=None):
        self.index_queryset(MyModel.objects.all(), using=using)

# views.py

from django.shortcuts import render

from haystack.views import SearchView

class MySearchView(SearchView):
    template_name = 'search/results.html'

    def search(self, request):
        query = request.GET.get('q')
        results = super().search(query)
        context = {
            'results': results,
        }
        return render(request, self.template_name, context)
# settings.py

HAYSTACK_CONNECTIONS = {
    'default': {
        'ENGINE': 'haystack.backends.whoosh_backend.WhooshEngine',
        'STORAGE': 'haystack.storage.filesystem.FileSystemStorage',
        'PATH': os.path.join(BASE_DIR, 'indexes'),
    },
}

# models.py

from haystack import indexes

class MyModelIndex(indexes.SearchIndex, indexes.Indexable):
    text = indexes.CharField(document=True, use_template=True)
    category = indexes.CharField(index_facet=True)
    tag = indexes.CharField(index_facet=True)

    def get_model(self):
        return MyModel

    def index_queryset(self, using=None):
        self.index_queryset(MyModel.objects.all(), using=using)

# views.py

from django.shortcuts import render

from haystack.views import FacetedSearchView

class MyFacetedSearchView(FacetedSearchView):
    template_name = 'search/results.html'

    def search(self, request):
        query = request.GET.get('q')
        results = super().search(query)
        context = {
            'results': results,
            'facets': self.get_facets(),
        }
        return render(request, self.template_name, context)
  • 検索対象となるモデルや、必要な検索機能に合わせて、適切な方法を選択してください。
  • 上記のコードはあくまで一例であり、ご自身のプロジェクトに合わせてカスタマイズする必要があります。


Haystack 以外の全文検索エンジン

データベースの全文検索機能

フロントエンドでの検索

これらの方法はそれぞれ異なるメリットとデメリットがあります。

  • フロントエンドでの検索
    セットアップが簡単で、ユーザーインターフェースに合わせた検索機能を提供できますが、サーバー側での処理が必要になる場合があります。
  • データベースの全文検索機能
    軽量でシンプルな方法ですが、検索速度や機能が限られる場合があります。
  • Haystack 以外の全文検索エンジン
    柔軟性と機能性に優れていますが、導入や運用が複雑になる場合があります。