16 декабря 2015 г. Django Python Elasticsearch Поисковые системы Linux

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 https://download.elasticsearch.org/elasticsearch/release/org/elasticsearch/distribution/tar/elasticsearch/2.1.0/elasticsearch-2.1.0.tar.gz
tar -xzf elasticsearch-2.1.0.tar.gz
cd elasticsearch-2.1.0/

Поставим сразу два полезных плагина:

# Anticipate Issues & Scale Faster
# https://www.elastic.co/products/marvel
./bin/plugin install elasticsearch/marvel/latest

# Monitoring and Management of instances and clusters
# https://github.com/royrusso/elasticsearch-HQ
./bin/plugin install royrusso/elasticsearch-HQ
Если у вас Linux запущен из под VirtualBox, то надо указать в настройках conf/elasticsearch.yml:
network.host: 0.0.0.0
discovery.zen.ping.unicast.hosts: ["10.0.2.2", "127.0.0.1", "[::1]"]
где 10.0.2.2 адрес хостовой машины. Узнать его можно в настройках сети VirtualBox, либо посмотреть откуда идут соединения с гостевой машиной netstat -an| grep SOMEPORT.

Отключаем агента марвела в conf/elasticsearch.yml, т.к. он нам сейчас не нужен:

marvel.agent.enabled: false

Запускаем ElasticSearch и проверяем, что сервис запущен:

./bin/elasticsearch

# Должен вернуться JSON
curl http://localhost:9200/

# Проверяем что работает веб-интерфейс Elastic HQ
curl http://localhost:9200/_plugin/hq/

Если что-то не работает, смотрите STDOUT запущенного инстанса elasticsearch.

Использование под Django

Загуглив готовое решение для удобной индексации моделей в Django, наткнулся на
django-elasticsearch, поставим его:

pip install elasticsearch
pip install git+https://github.com/liberation/django_elasticsearch.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, спасибо!

Оставьте свой комментарий

Markdown