Поиск Django Rest Framework С Помощью Elasticsearch

Пользователи ищут товары в интернет-магазине, ищут артикулы; поиск является неотъемлемой частью сайта.

Быстрый и гибкий поиск сложно реализовать с помощью реляционных баз данных.

Для таких задач используются поисковые системы, одна из которых Эластичный поиск .

Elasticsearch хорошо документирован и доступен на AWS «из коробки».

Библиотека используется для работы с elasticsearch. elasticsearch-py или elasticsearch-dsl-py .

elasticsearch-dsl-py — это расширенный набор elasticsearch-py, он прост в использовании и поддерживает elasticsearch версии 5.x. На основе этой библиотеки была создана библиотека Джанго-рест-elasticsearch , в основе которого лежит идеология существующего поиска в REST-фреймворк Джанго .

Ниже я подробно опишу, как реализовать поиск в Django REST Framework с помощью elasticsearch с использованием этой библиотеки.

В качестве примера рассмотрим реализацию простого блога с фильтрацией по тегам и поиском по заголовкам статей.



Монтаж

Процесс установки 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, который будет отправлять уведомления при возникновении изменений в модели.

Прежде чем создавать сигнал, давайте создадим сериализатор для преобразования объекта 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 .

Надеюсь, статья поможет вам реализовать поиск в вашем проекте.

Теги: #django #django rest framework #elasticsearch #python #django

Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.