ElasticsearchとDockerを使用したDjangoの統合


まず、Dockerをインストールしてセットアップします。Dockerは、環境の独立性と再現性を提供するため、開発とデプロイのプロセスを簡素化します。公式のDockerドキュメントを参照して、適切な手順に従ってDockerをインストールしてください。

次に、Djangoプロジェクトを作成します。ターミナルで以下のコマンドを実行して、新しいDjangoプロジェクトを作成します。

$ django-admin startproject myproject

プロジェクトディレクトリに移動して、Elasticsearchを含むDjangoアプリケーションを作成します。

$ cd myproject
$ python manage.py startapp searchapp

ElasticsearchをDockerコンテナで実行するために、docker-compose.ymlファイルを作成します。以下は、サンプルのdocker-compose.ymlファイルです。

version: '3'
services:
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.10.1
    ports:
      - 9200:9200
    environment:
      - discovery.type=single-node

このファイルをプロジェクトのルートディレクトリに保存します。

次に、Djangoの設定を変更して、Elasticsearchを使用するようにします。settings.pyファイルを開き、以下のように変更します。

# settings.py
# Elasticsearchのホストとポートを設定
ELASTICSEARCH_HOST = 'localhost'
ELASTICSEARCH_PORT = 9200
# Elasticsearchバックエンドを有効化する
INSTALLED_APPS = [
    ...
    'django_elasticsearch_dsl',
    'searchapp',
]
# Elasticsearchバックエンドの設定
ELASTICSEARCH_DSL = {
    'default': {
        'hosts': f'{ELASTICSEARCH_HOST}:{ELASTICSEARCH_PORT}',
    },
}

次に、searchapp内にElasticsearchに対するモデルと検索ビューを作成します。以下は、サンプルのコード例です。

# searchapp/models.py
from django_elasticsearch_dsl import Document, fields
from django_elasticsearch_dsl.registries import registry
from elasticsearch_dsl import analyzer
from .models import BlogPost
html_strip = analyzer('html_strip', tokenizer="standard", filter=["lowercase", "stop", "snowball"])
@registry.register_document
class BlogPostDocument(Document):
    title = fields.TextField(attr='title')
    content = fields.TextField(
        analyzer=html_strip,
        fields={'raw': fields.KeywordField()}
    )

    class Django:
        model = BlogPost
# searchapp/views.py
from django.shortcuts import render
from django.views import View
from django_elasticsearch_dsl.search import Search
from .models import BlogPostDocument
class BlogPostSearchView(View):
    def get(self, request):
        query = request.GET.get('q')
        if query:
            search = Search(index='blogpost_index')
            search = search.query("multi_match", query=query, fields=['title', 'content'])
            results = search.execute()
        else:
            results = []
        return render(request, 'searchapp/search_results.html', {'results': results})

以上のコードでは、BlogPostDocumentクラスがElasticsearchのドキュメントとして定義されており、BlogPostSearchViewクラスが検索ビューとして定義されています。検索ビューでは、ユーザーがクエリを入力すると、Elasticsearchに対してクエリを発行し、結果を取得して表示します。

最後に、urls.pyファイルを開き、以下のようにURLパターンとビューを追加します。

# urls.py
from django.urls import path
from searchapp.views import BlogPostSearchView
urlpatterns = [
    ...
    path('search/', BlogPostSearchView.as_view(), name='blogpost_search'),
]

これで、Elasticsearchを使用したDjangoアプリケーションのセットアップが完了しました。以下の手順を実行して、アプリケーションを起動します。

$ docker-compose up -d
$ python manage.py makemigrations
$ python manage.py migrate
$ python manage.py runserver

ブラウザでhttp://localhost:8000/search/?q=queryにアクセスすると、検索結果が表示されます。queryの部分を検索したいキーワードに置き換えて試してみてください。

このブログ投稿では、ElasticsearchとDockerを使用してDjangoに全文検索機能を統合する方法を説明しました。このセットアップを基に、さまざまなカスタマイズや高度な検索オプションを追加することが可能です。詳細については、公式のElasticsearchとDjangoのドキュメントを参照してください。