Django. Знакомство с ElasticSearch
Понадобилось на одном из своих проектов установить FTS сервис. Я достаточно долгое время пользовался SphinxSearch, но решил поинтересоваться у общественности (тут и тут) какой сейчас инструмент более популярен и отвечает следующим требованиям:

- Русская морфология и стемминг
- Фасетный поиск (аттрибуты)
- Удобное API для поиска и индексации
- Простота маштабирования
- Желательно иметь real-time индексы
- Желательно наличие админки для анализа и управления индексами
Большинство коллег использует ElasticSearch, почитав про него несколько статей и посмотрев несколько видео с презентациями решил попробовать вторую версию, а именно ElasticSearch 2.1. Также вспомнил, что LogStash стал частью elastic, а я на него давно уже гляжу в качестве замены Sentry.
Если кратко, то ElasticSearch, как и Solr, представляет из себя некую оболочку вокруг Lucene. Но именно в этой оболечке все вкусности этого замечательного поискового движка: фасеты, HTTP-JSON API, multitenant (возможность кастомизации поискового индекса под разные группы пользователей), масштабирование, удобный дашборд.
Установка ElasticSearch 2.1
В пакетах Ubuntu 15.10 лежит старая версия 1.6.2, указывать какой-либо ppa я не стал, решил для тестового использования скачать просто архив с официального сайта:
curl -L -O tar -xzf elasticsearch-2.1.0.tar.gz cd elasticsearch-2.1.0/
Поставим сразу два полезных плагина:
# Anticipate Issues & Scale Faster # ./bin/plugin install elasticsearch/marvel/latest # Monitoring and Management of instances and clusters # ./bin/plugin install royrusso/elasticsearch-HQ
Если у вас Linux запущен из под VirtualBox, то надо указать в настройках conf/elasticsearch.yml:где 10.0.2.2 адрес хостовой машины. Узнать его можно в настройках сети VirtualBox, либо посмотреть откуда идут соединения с гостевой машиной netstat -an| grep SOMEPORT.network.host: 0.0.0.0 discovery.zen.ping.unicast.hosts: ["10.0.2.2", "127.0.0.1", "[::1]"]
Отключаем агента марвела в conf/elasticsearch.yml, т.к. он нам сейчас не нужен:
marvel.agent.enabled: false
Запускаем ElasticSearch и проверяем, что сервис запущен:
./bin/elasticsearch # Должен вернуться JSON curl # Проверяем что работает веб-интерфейс Elastic HQ curl
Если что-то не работает, смотрите STDOUT запущенного инстанса elasticsearch.
Использование под Django
Загуглив готовое решение для удобной индексации моделей в Django, наткнулся на
django-elasticsearch, поставим его:
pip install elasticsearch pip install git+
Дальше по документации в README.md меняем нашу модель:
from django.db import models from django_elasticsearch.models import EsIndexable class Tag(EsIndexable, models.Model): name = models.CharField(max_length=64) [...]
Укажем имя индекса в settings.py:
ELASTICSEARCH_DEFAULT_INDEX = '<project_name>'
Запускаем индекс:
./manage.py shell >>> from products.models import Tag >>> Tag.es.create_index() >>> Tag.es.reindex_all()
Удобно при этом смотреть в Elastic HQ и видеть как наполнился наш индекс.
Дальше пробуем поискать:
>>> Tag.es.search('something') [{u'description': u'', u'name': u'Something', u'id': 1}, {u'description': u'', u'name': u'SomeThing2', u'id': 2}, ...] >>> Tag.es.search('something').deserialize() [<Tag: 1 Something>, <Tag: 2 SomeThing2>]
Вешаемся на сигналы и меняем в реалтайме индекс
Для этого надо в settings.py указать:
ELASTICSEARCH_AUTO_INDEX = True
Теперь используя сигналы "post_syncdb", "post_save" и "post_delete" мы будем уведомлять поисковый механизм о новых изменениях в модели. Делать ничего не надо, любое изменение или удаление объекта в подключенной через миксин EsIndexable модели будет немедленно применено в ElasticSearch.
Комментарии
для поиграться прекрасно подходит бесплатный https://aws.amazon.com/ru/elasticsearch-service/
@slav0nic, спасибо!
Оставьте свой комментарий