Как в Python индексировать и запрашивать данные с помощью Haystack и Elasticsearch

Как в Python индексировать и запрашивать данные с помощью Haystack и Elasticsearch

От автора: Haystack — это библиотека Python, которая обеспечивает модульный поиск для Django. Haystack Python имеет API, который обеспечивает поддержку различных поисковых запросов, таких как Elasticsearch, Whoosh, Xapian и Solr.

Elasticsearch

Elasticsearch — популярная поисковая система Lucene, способная выполнять полнотекстовый поиск, она разработана на Java. В поиске Google используется тот же подход, что и при индексации их данных, и поэтому получить любую информацию с помощью всего нескольких ключевых слов очень легко.

Установите Django Haystack и Elasticsearch

Первый шаг — настройте Elasticsearch и запустить его локально на вашей машине. Elasticsearch требует Java, поэтому на вашем компьютере должен быть установлен Java. Мы собираемся следовать инструкциям с сайта Elasticsearch. Загрузите архив Elasticsearch 1.4.5 следующим образом:

curl -L -O https://download.elastic.co/elasticsearch/elasticsearch/elasticsearch-1.4.5.tar.gz

Распакуйте его:

tar -xvf elasticsearch-1.4.5.tar.gz

Затем он создаст пакет файлов и папок в вашем текущем каталоге. После этого перейдите в каталог bin:

cd elasticsearch-1.4.5/bin

Запустите Elasticsearch.

./elasticsearch

Чтобы убедиться, что он успешно установлен, перейдите к http://127.0.0.1:9200/, вы должны увидеть что-то вроде этого.

{ "name" : "W3nGEDa", "cluster_name" : "elasticsearch", "cluster_uuid" : "ygpVDczbR4OI5sx5lzo0-w", "version" : { "number" : "5.6.3", "build_hash" : "1a2f265", "build_date" : "2017-10-06T20:33:39.012Z", "build_snapshot" : false, "lucene_version" : "6.6.1" }, "tagline" : "You Know, for Search"
}

Убедитесь, что у вас также установлен haystack.

pip install django-haystack

Давайте создадим проект Django. Проект сможет индексировать всех клиентов в банке, упрощая поиск и получение данных, используя всего несколько поисковых терминов.

django-admin startproject Bank

Эта команда создает файлы, которые предоставляют конфигурации для проектов Django. Давайте создадим приложение для клиентов.

cd Bank python manage.py startapp customers

Конфигурации settings.py

Чтобы использовать Elasticsearch для индексации контента, доступного для поиска, нам нужно определить внутренний параметр для haystack в файле проекта settings.py. Мы собираемся использовать Elasticsearch в качестве бэк-енд. HAYSTACK_CONNECTIONS является обязательным параметром и должен выглядеть следующим образом:

HAYSTACK_CONNECTIONS = { 'default': { 'ENGINE': 'haystack.backends.elasticsearch_backend.ElasticsearchSearchEngine', 'URL': 'http://127.0.0.1:9200/', 'INDEX_NAME': 'haystack', },
}

В settings.py мы также собираемся добавить haystack и клиентов в список installed apps.

INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'rest_framework', 'haystack', 'customer'
]

Создание модели

Давайте создадим модель для клиентов. В customers/models.py добавьте следующий код.

from __future__ import unicode_literals from django.db import models # Create your models here.
customer_type = ( ("Active", "Active"), ("Inactive", "Inactive")
) class Customer(models.Model): id = models.IntegerField(primary_key=True) first_name = models.CharField(max_length=50, null=False, blank=True) last_name = models.CharField( max_length=50, null=False, blank=True) other_names = models.CharField(max_length=50, default=" ") email = models.EmailField(max_length=100, null=True, blank=True) phone = models.CharField(max_length=30, null=False, blank=True) balance = models.IntegerField(default="0") customer_status = models.CharField( max_length=100, choices=customer_type, default="Active") address = models.CharField( max_length=50, null=False, blank=False) def save(self, *args, **kwargs): return super(Customer, self).save(*args, **kwargs) def __unicode__(self): return "{}:{}".format(self.first_name, self.last_name)

Зарегистрируйте модель Customer в admin.py следующим образом:

from django.contrib import admin
from .models import Customer # Register your models here. admin.site.register(Customer)

Создание базы данных и суперпользователя

Примените миграции и создайте учетную запись администратора.

python manage.py migrate
python manage.py createsuperuser

Запустите сервер и перейдите по адресу http://localhost:8000/admin/. Теперь вы сможете увидеть свою модель клиента. Идем дальше и добавляем новых клиентов.

Индексирование данных

Чтобы проиндексировать наши модели, мы начинаем с создания SearchIndex. Объекты SearchIndex определяют, какие данные должны быть помещены в поисковый индекс. Каждый тип модели должен иметь уникальный searchIndex.

Объекты SearchIndex — это то, как haystack определяет, какие данные должны быть помещены в поисковый индекс, и обрабатывает поток данных. Чтобы построить SearchIndex, мы собираемся реализовать наследование от indexes, SearchIndex и indexes.Indexable, определить поля, в которых мы хотим хранить наши данные и определить метод get_model.

Давайте создадим CustomerIndex в соответствии модели Customer. Создайте файл search_indexes.py в каталоге приложения клиентов и добавьте в него следующий код.

from .models import Customer
from haystack import indexes class CustomerIndex(indexes.SearchIndex, indexes.Indexable): text = indexes.EdgeNgramField(document=True, use_template=True) first_name = indexes.CharField(model_attr='first_name') last_name = indexes.CharField(model_attr='last_name') other_names = indexes.CharField(model_attr='other_names') email = indexes.CharField(model_attr='email', default=" ") phone = indexes.CharField(model_attr='phone', default=" ") balance = indexes.IntegerField(model_attr='balance', default="0") customer_status = indexes.CharField(model_attr='customer_status') address = indexes.CharField(model_attr='address', default=" ") def get_model(self): return Customer def index_queryset(self, using=None): return self.get_model().objects.all()

Поле EdgeNgramField — это haystack SearchIndex, который предотвращает неправильные совпадения, когда части двух разных слов смешиваются друг с другом.

Это позволяет нам использовать функцию autocomplete для проведения запросов. Мы будем использовать автозаполнение, когда начнем запрашивать данные.

document=True указывает основное поле для поиска. Кроме того, поле use_template=True в text позволяет нам использовать шаблон данных для построения документа, который будет проиндексирован.

Давайте создадим шаблон в каталоге шаблонов клиентов. В файле search/indexes/customers/customers_text.txt добавьте следующее:

{{object.first_name}}
{{object.last_name}}
{{object.other_names}}

Переиндексирование данных

Теперь, когда наши данные находятся в базе данных, пришло время поместить их в поисковый индекс. Для этого просто запустите ./manage.py rebuild_index. Вы получите сумму того, сколько моделей было обработано и помещено в индекс.

Indexing 20 customers

Кроме того, вы можете использовать RealtimeSignalProcessor, который автоматически обрабатывает обновления / удаления. Чтобы использовать его, добавьте следующее в файл settings.py.

HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'

Запрос данных

Мы собираемся использовать шаблон поиска и Haystack API для запроса данных.

Шаблон поиска

Добавьте URL-адреса haystack в URLconf.

url(r'^search/', include('haystack.urls')),

Давайте создадим шаблон поиска. В templates/search.html, добавьте следующий код.

{% block head %}
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script> {% endblock %}
{% block navbar %} <nav class="navbar navbar-default"> <div class="container"> <div class="navbar-header"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#myNavbar"> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="#">HOME</a> </div> <div class="collapse navbar-collapse" id="myNavbar"> <ul class="nav navbar-nav navbar-right"> <li><input type="submit" class="btn btn-primary" value="Add Customer"> </li> </ul> </div> </div>
</nav>
{% endblock %}
{% block content %}
<div class="container-fluid bg-3 text-center"> <form method="get" action="." class="form" role="form"> {{ form.non_field_errors }} <div class="form-group"> {{ form.as_p }} </div> <div class="form-group"> <input type="submit" class="btn btn-primary" value="Search"> </div> {% if query %} <h3>Results</h3> <div class="container-fluid bg-4 text-left"> <div class="row"> {% for result in page.object_list %} <div class="col-sm-4"> <div class="thumbnail"> <div class="form-group"> <p>First name : {{result.first_name}} </p> </div> <div class="form-group"> <p>Last name : {{result.last_name}} </p> </div> <div class="form-group"> <p>Balance : {{result.balance}} </p> </div> <div class="form-group"> <p>Email : {{result.email}} </p> </div> <div class="form-group"> <p>Status : {{result.customer_status}} </p> </div> </div> </div> {% empty %} <p style="text-center">No results found.</p> {% endfor%} </div> </div> {% endif %}
</form>
</div> {% endblock %}

Это список page.object_list объектов SearchResult, который позволяет нам получить отдельные объекты модели, например result.first_name. Ваша полная структура проекта должна выглядеть примерно так:

Как в Python индексировать и запрашивать данные с помощью Haystack и Elasticsearch

Теперь запустите сервер, перейдите к 127.0.0.1:8000/search/ и выполните поиск, как показано ниже.

Как в Python индексировать и запрашивать данные с помощью Haystack и Elasticsearch

Поиск по Albert даст результаты всех клиентов с именем Albert. Если ни один клиент не имеет имени Альберт, то запрос даст пустые результаты. Вы можете поэкспериментировать с собственными данными.

Haystack API

Haystack имеет класс SearchQuerySet, предназначенный для упрощения и согласованности поиска и повторения результатов. Большая часть SearchQuerySetAPI знакома из Django ORM QuerySet. В customers/views.py добавьте следующий код:

from django.shortcuts import render
from rest_framework.decorators import ( api_view, renderer_classes,
)
from .models import Customer
from haystack.query import SearchQuerySet from rest_framework.response import Response
# Create your views here. @api_view(['POST'])
def search_customer(request): name = request.data['name'] customer = SearchQuerySet().models(Customer).autocomplete( first_name__startswith=name) searched_data = [] for i in customer: all_results = {"first_name": i.first_name, "last_name": i.last_name, "balance": i.balance, "status": i.customer_status, } searched_data.append(all_results) return Response(searched_data)

autocomplete — это ярлык для выполнения автозаполнения поиска. Он должен быть запущен для полей, либо EdgeNgramField, либо NgramField.

В Queryset выше мы используем метод contains для фильтрации поиска, чтобы получить только результаты, которые содержат определенные символы. Например, Al будет только получать информацию о клиентах с именем, содержащим Al. Обратите внимание, что результаты будут получены только из полей, определенных в файле customer_text.txt.

Как в Python индексировать и запрашивать данные с помощью Haystack и Elasticsearch

Помимо поиска contains, для выполнения запросов доступны и другие варианты, в том числе:

content

contains

exact

gt

gte

lt

lte

in

startswith

endswith

range

fuzzy

Заключение

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

Elasticsearch также широко используется для поиска контента, анализа данных и запросов. Для получения дополнительной информации посетите сайты Haystack и Elasticsearch.

Автор: Esther Vaati

Источник: https://code.tutsplus.com

Редакция: Команда webformyself.