ユーザーはオンラインストアで製品を探し、記事を探しています。検索はサイトの不可欠な要素です。 リレーショナルデータベースを使用した高速で柔軟な検索の実装は困難です。 そのようなタスクには、検索エンジンが使用されます。そのうちの1つはElasticsearchです。 Elasticsearchは十分に文書化されており、AWSですぐに使用できます。
elasticsearchを使用するには、 elasticsearch-pyまたはelasticsearch-dsl-pyライブラリを使用します。 elasticsearch-dsl-pyはelasticsearch-pyのアドオンであり、使いやすく、elasticsearchバージョン5.xをサポートしています。 このライブラリに基づいて、 Django REST Frameworkの既存の検索のイデオロギーに基づいたdjango-rest-elasticsearchライブラリが作成されました。 以下に、このライブラリを使用してelasticsearchを使用してDjango REST Frameworkで検索を実装する方法を詳細に説明します。
例として、タグによるフィルタリングと記事タイトルによる検索を備えたシンプルなブログの実装を検討してください。
設置
elasticsearchとdjangoのインストールプロセスの詳細については、公式ドキュメントをご覧ください。 パッケージをインストールすると、すべてが非常に簡単になります
pip install django-rest-elasticsearch
モデルとインデックスを作成する
モデルを作成する
class Blog(models.Model): title = models.CharField(_('Title'), max_length=1000) created_at = models.DateTimeField(_('Created at'), auto_now_add=True) body = models.TextField(_('Body')) tags = ArrayField(models.CharField(max_length=200), blank=True, null=True) is_published = models.BooleanField(_('Is published'), default=False) def __str__(self): return self.title
モデルを作成した後、モデルをelasticsearchドキュメントとして説明します。
class BlogIndex(DocType): pk = Integer() title = Text(fields={'raw': Keyword()}) created_at = Date() body = Text() tags = Keyword(multi=True) is_published = Boolean() class Meta: index = 'blog'
これで、elasticsearchでインデックスを作成できます
BlogIndex.init()
elasticsearchでのドキュメントの自動更新
モデルとインデックスを作成した後、モデルの変更をelasticsearchに表示する必要があります。 最良の方法は、モデルの変更が発生したときに通知を送信するジャンゴ信号を追加することです。 信号を作成する前に、Djangoオブジェクトをelasticsearchドキュメントに変換するシリアライザーを作成します
from rest_framework_elasticsearch.es_serializer import ElasticModelSerializer from .models import Blog from .search_indexes import BlogIndex class ElasticBlogSerializer(ElasticModelSerializer): class Meta: model = Blog es_model = BlogIndex fields = ('pk', 'title', 'created_at', 'tags', 'body', 'is_published')
信号を追加します
from django.db.models.signals import pre_save, post_delete from django.dispatch import receiver from .serializers import Blog, ElasticBlogSerializer @receiver(pre_save, sender=Blog, dispatch_uid="update_record") def update_es_record(sender, instance, **kwargs): obj = ElasticBlogSerializer(instance) obj.save() @receiver(post_delete, sender=Blog, dispatch_uid="delete_record") def delete_es_record(sender, instance, *args, **kwargs): obj = ElasticBlogSerializer(instance) obj.delete(ignore=404)
信号を追加した後、モデルへの変更はelasticsearchで即座に行われます
ビューを作成
検索とフィルタリングのためのビューを作成しましょう。
from elasticsearch import Elasticsearch, RequestsHttpConnection from rest_framework_elasticsearch import es_views, es_filters from .search_indexes import BlogIndex class BlogView(es_views.ListElasticAPIView): es_client = Elasticsearch(hosts=['elasticsearch:9200/'], connection_class=RequestsHttpConnection) es_model = BlogIndex es_filter_backends = ( es_filters.ElasticFieldsFilter, es_filters.ElasticSearchFilter ) es_filter_fields = ( es_filters.ESFieldFilter('tag', 'tags'), ) es_search_fields = ( 'tags', 'title', )
それだけです、検索例
http://example.com/blogs/api/list?search=elasticsearch http://example.com/blogs/api/list?tag=opensource http://example.com/blogs/api/list?tag=opensource,aws
完全なサンプルコードはgithubで入手できます。 この記事が、プロジェクトでの検索の実現に役立つことを願っています。