Djangoで検索結果を絞り込む:Haystackを使った属性検索
Simple full-text search
これは、最もシンプルで使いやすい検索方法です。全文検索エンジンである Haystack
を利用し、モデル内の全てのフィールドを対象に検索を行います。
実装手順
Haystack
とWhoosh
をインストールします。
pip install haystack whoosh
settings.py
ファイルに以下の設定を追加します。
HAYSTACK_CONNECTIONS = {
'default': {
'ENGINE': 'haystack.backends.whoosh_backend.WhooshEngine',
'STORAGE': 'haystack.storage.filesystem.FileSystemStorage',
'PATH': os.path.join(BASE_DIR, 'indexes'),
},
}
- 検索対象となるモデルを登録します。
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)
- コマンドを実行して全文インデックスを作成します。
python manage.py haystack rebuild
- 検索ビューを作成します。
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
これは、より高度な検索機能を実装したい場合に役立つ方法です。カテゴリーやタグなどの属性に基づいて絞り込み検索を行うことができます。
実装手順
-
Simple full-text search
と同様に、Haystack
とWhoosh
をインストールして設定を行います。 -
検索対象となるモデルを登録します。
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)
- コマンドを実行して全文インデックスを作成します。
python manage.py haystack rebuild
- 検索ビューを作成します。
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 以外の全文検索エンジン
柔軟性と機能性に優れていますが、導入や運用が複雑になる場合があります。