Рубрики
Без рубрики

Elasticsearch с Джанго легким способом

Автор оригинала: FreeCodeCapm Team.

Адам Уотрис

Некоторое время назад я работал над проектом Django и хотел реализовать быстрый бесплатный текстовый поиск. Вместо того, чтобы использовать обычную базу данных для этой функции поиска – например, MySQL или PostgreSQL – я решил использовать базу данных NoSQL. То есть когда я обнаружил Elasticsearch Отказ

Elasticsearch Index Tocuments Для ваших данных вместо использования таблиц данных, как обычная реляционная база данных. Это ускоряет поиск и предлагает множество других преимуществ, которые вы не получаете с обычной базой данных. Я также держал обычную реляционную базу данных для хранения деталей пользователей, логинов и других данных, которые Elasticsearch не нужно индексировать.

После длительного поиска о том, как правильно реализовать Elasticsearch с Django, я действительно не нашел никаких удовлетворительных ответов. Некоторые Руководства или учебники были запутаны и, казалось, принимали ненужные шаги, чтобы индексировать данные в Elasticsearch. Было довольно много информации о том, как выполнить поиск, но не так много о том, как следует сделать индексацию. Я чувствовал, что там должен быть простое решение там, поэтому я решил попробовать себя.

Я хотел сохранить его как можно просто, потому что простые решения, как правило, являются лучшими на мой взгляд. Поцелуй (держите его просто глупый), меньше, и все эти вещи – это то, что резонирует со мной много, особенно когда все другое решение там сложно. Я решил использовать пример Honza Král в Это видео иметь что-то, чтобы основать мой код на. Я рекомендую смотреть его, хотя в этот момент это немного устарело.

Поскольку я использовал Django – который написан в Python – было легко взаимодействовать с Elasticsearch. Есть два клиентских библиотеках для взаимодействия с Elasticsearch Iearch с Python. Есть elasticsearch-py , который является официальным низкоуровневым клиентом. И есть elasticsearch-dsl , который основан на первом, но дает абстракцию более высокого уровня с немного менее функциональностью.

Мы скоро попадем в какой-то пример, но сначала мне нужно уточнить, что мы хотим сделать:

  • Настройка Elasticsearch на нашей местной машине и обеспечение того, чтобы он работает правильно
  • Настройка нового проекта Django
  • Массовая индексация данных, которые уже в базе данных
  • Индексирование каждого нового экземпляра, что пользователь сохраняет в базе данных
  • Основной пример поиска

Хорошо, что кажется достаточно простым. Давайте начнем при установке Elasticsearch на нашей машине. Также все Код будет доступен на моем github Так что вы можете легко следовать примерам.

Установка Elasticsearch

Поскольку elasticsearch работает на Java, вы должны убедиться, что у вас обновлена версия JVM. Проверьте, какую версию у вас есть Java -version в терминале. Затем вы запускаете следующие команды для создания нового каталога, загрузить, извлечь и запустить Elasticsearch:

mkdir elasticsearch-example
wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-5.1.1.tar.gz
tar -xzf elasticsearch-5.1.1.tar.gz
./elasticsearch-5.1.1/bin/elasticsearch

Когда elasticsearch запускается там, должно быть много вывода, напечатанного в окно терминала. Чтобы проверить, что он работает и работает правильно открыть новое окно терминала и запустить этот Curl команда:

curl -XGET http://localhost:9200

Ответ должен быть что-то вроде этого:

{  "name" : "6xIrzqq",  "cluster_name" : "elasticsearch",  "cluster_uuid" : "eUH9REKyQOy4RKPzkuRI1g",  "version" : {    "number" : "5.1.1",    "build_hash" : "5395e21",    "build_date" : "2016-12-06T12:36:15.409Z",    "build_snapshot" : false,    "lucene_version" : "6.3.0"  },  "tagline" : "You Know, for Search"

Отлично, у вас сейчас есть Elasticsearch, работающий на вашей местной машине! Пришло время настроить ваш проект Django.

Настройка проекта Django

Сначала вы создаете виртуальную среду с Virtualenv Venv и введите его с Источник Venv/Bin/Activate чтобы все сохранить. Затем вы устанавливаете некоторые пакеты:

pip install djangopip install elasticsearch-dsl

Чтобы запустить новый проект Django, который вы запускаете:

django-admin startproject elasticsearchprojectcd elasticsearchprojectpython manage.py startapp elasticsearchapp

После создания новых проектов Django вам нужно создать модель, которую вы будете использовать. Для этого руководства я решил пойти с хорошим старым приведенным в блоге в блоге. В Models.py Вы размещаете следующий код:

from django.db import modelsfrom django.utils import timezonefrom django.contrib.auth.models import User# Create your models here.# Blogpost to be indexed into ElasticSearchclass BlogPost(models.Model):   author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='blogpost')   posted_date = models.DateField(default=timezone.now)   title = models.CharField(max_length=200)   text = models.TextField(max_length=1000)

Довольно прямо вперед. Не забудьте добавить elasticsearchApp к Stall_apps в settings.py и зарегистрируйте новую модель BlogPost в admin.py как это:

from django.contrib import adminfrom .models import BlogPost# Register your models here.# Need to register my BlogPost so it shows up in the adminadmin.site.register(BlogPost)

Вы также должны Python Manage.py Makemigrations , Python Manage.py Миграция и Python Manage.py CreateSuperUser Чтобы создать базу данных и учетную запись администратора. Теперь Python Manage.py Runserver пойти в http://localhost: 8000/admin/ и логин. Теперь вы должны быть в состоянии увидеть ваши сообщения постов в блоге там. Продолжай и создайте свой первый пост в блоге в администрате.

Поздравляем, теперь у вас есть функционирующий проект Django! Наконец, время попасть в забавные вещи – подключение Elasticsearch.

Соединение Elasticsearch с Django

Вы начинаете с создания нового файла под названием search.py в нашем elasticsearchApp каталог. Вот где будет жить код elasticsearch. Первое, что вам нужно сделать, состоит в том, чтобы создать соединение из приложения Django в Elasticsearch. Вы делаете это в своем search.py файл:

from elasticsearch_dsl.connections import connectionsconnections.create_connection()

Теперь, когда у вас есть глобальное подключение к вашим эластичном настроек, вам необходимо определить, что вы хотите индексировать в нем. Написать этот код:

from elasticsearch_dsl.connections import connectionsfrom elasticsearch_dsl import DocType, Text, Dateconnections.create_connection()class BlogPostIndex(DocType):    author = Text()    posted_date = Date()    title = Text()    text = Text()    class Meta:        index = 'blogpost-index'

Это выглядит довольно похоже на вашу модель, верно? Дотний Работает как обертка, чтобы позволить вам написать индекс, как модель, и Текст и Дата являются полями, так что они получают правильный формат, когда они будут проиндексированы.

Внутри мета высказаете elasticsearch, что вы хотите, чтобы индекс был назван. Это будет иметь значение ссылки на elasticsearchearch, чтобы он знал, какой индекс он имеет дело при инициализации его в базе данных и сохранение каждого созданного нового экземпляра объекта.

Теперь вам нужно на самом деле создать отображение вашего вновь созданного Blogpostindex в elasticsearch. Вы можете сделать это, а также создать способ сделать массовую индексацию одновременно – насколько удостоверен?

Массовая индексация данных

Облигация Команда находится в elasticsearch.helpers который включен при установке elasticsearch_dsl Так как он построен на вершине этой библиотеки. Сделать следующее в search.py :

...from elasticsearch.helpers import bulkfrom elasticsearch import Elasticsearchfrom . import models...
...def bulk_indexing():    BlogPostIndex.init()    es = Elasticsearch()    bulk(client=es, actions=(b.indexing() for b in models.BlogPost.objects.all().iterator()))

“Что здесь происходит?” Вы можете думать. Это не так сложно, на самом деле.

Так как вы только хотите сделать насыпную индексацию, когда вы что-то измените в нашей модели, вы init () Модель, которая отображает ее в elasticsearch. Тогда вы используете Облигация и пропустите его экземпляром Elasticsearch () который создаст связь с Elasticsearch. Затем вы проходите генератор в действия = и итерации за все Blogpost Объекты, которые у вас есть в вашей обычной базе данных и позвоните в .indexing () Метод на каждом объекте. Почему генератор? Потому что, если у вас было много объектов, чтобы проиграть по поводу генератора, не пришлось бы сначала загрузить их в память.

Есть только одна проблема с вышеуказанным кодом. У вас нет .indexing () Способ на вашей модели еще. Давайте исправить это:

...from .search import BlogPostIndex...
...# Add indexing method to BlogPostdef indexing(self):   obj = BlogPostIndex(      meta={'id': self.id},      author=self.author.username,      posted_date=self.posted_date,      title=self.title,      text=self.text   )   obj.save()   return obj.to_dict(include_meta=True)

Вы добавляете метод индексации к Блог пост модель. Возвращает Индекс blog post и сохраняется в elasticsearch.

Давайте попробуем это сейчас и посмотрите, сможете ли вы набрать индекс в блоге, который вы ранее создали. Бег Python Manage.py Shell Вы идете в раковину Django и импортируйте свой search.py с От elasticsearchapp.search Import * а потом беги Bulk_indexing () Чтобы индексировать все сообщения в блоге в вашей базе данных. Чтобы посмотреть, работает ли он, вы запускаете следующую команду CURL:

curl -XGET 'localhost:9200/blogpost-index/blog_post_index/1?pretty'

Вы должны вернуть свой первый пост в блоге в терминале.

Индексирование недавно сохраненного экземпляра

Далее вам нужно добавить сигнал, который загорится .indexing () На каждом новом экземпляре, который сохраняется каждый раз, когда пользователь сохраняет новый пост блога. В elasticsearchApp Создайте новый файл под названием сигналы.пи и добавить этот код:

from .models import BlogPostfrom django.db.models.signals import post_savefrom django.dispatch import receiver@receiver(post_save, sender=BlogPost)def index_post(sender, instance, **kwargs):    instance.indexing()

post_save Сигнал гарантирует, что сохраненный экземпляр будет индексироваться с помощью .indexing () Метод после его сохранения.

Чтобы это работать, нам также нужно зарегистрировать Django, который мы используем сигналы. Мы делаем это открытие Apps.py и добавление следующего кода:

from django.apps import AppConfigclass ElasticsearchappConfig(AppConfig):    name = 'elasticsearchapp'    def ready(self):        import elasticsearchapp.signals

Чтобы завершить это, нам также нужно сказать Django, что мы используем эту новую конфигурацию. Мы делаем это внутри __init__.py внутри нашего elasticsearchApp каталог, добавив:

default_app_config = 'elasticsearchapp.apps.ElasticsearchappConfig'

Теперь post_save Сигнал зарегистрирован с Django и готов слушать, когда сохраняется новый блогпост.

Попробуйте наше, переходя в админ Джанго снова и сохраняя новый блогпост. Затем проверьте с Curl Команда, если он был успешно проиндексирован в elasticsearch.

Простой поиск

Теперь давайте сделаем простую функцию поиска в search.py Чтобы найти все сообщения, фильтрованные автором:

...from elasticsearch_dsl import DocType, Text, Date, Search...
...def search(author):    s = Search().filter('term', author=author)    response = s.execute()    return response

Давайте попробуем поиск. В оболочке: От elasticsearchapp.search Import * и беги Печать (поиск (автор = »<имя автор и GT;”)):

>>> print(search(author="home"))]>

Там у вас есть! Теперь вы успешно индексировали все ваши экземпляры в Elasticsearch, создали post_save Сигнал, который индексирует каждый недавно сохраненный экземпляр, и создал функцию для поиска нашей базы данных ElaSticsearch для ваших данных.

Заключение

Это была довольно длительная статья, но я надеюсь, что она написана достаточно простыми, даже для того, чтобы новичок мог быть в состоянии понять.

Я объяснил, как подключить модель Django для Elasticsearch для индексации и поиска, но есть намного больше, что Elasticsearch может сделать. Я рекомендую прочитать на своем веб-сайте и изучать, какие другие существуют другие возможности, такие как пространственные операции и полный текстовый поиск с интеллектуальным выделением. Это отличный инструмент, и я обязательно использую его в будущих проектах!

Если вам понравилась эта статья или есть комментарий или предложение, пожалуйста, не стесняйтесь оставлять сообщение ниже. И оставаться настроен на более интересные вещи!