От автора: 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. Ваша полная структура проекта должна выглядеть примерно так:
Теперь запустите сервер, перейдите к 127.0.0.1:8000/search/ и выполните поиск, как показано ниже.
Поиск по 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.
Помимо поиска contains, для выполнения запросов доступны и другие варианты, в том числе:
content
contains
exact
gt
gte
lt
lte
in
startswith
endswith
range
fuzzy
Заключение
В социальных сетях, здравоохранении, магазинах и других секторах в каждый момент времени генерируется огромное количество данных. Большая часть этих данных неструктурирована. Elasticsearch может использоваться для обработки и анализа этих данных в форме, которая может быть понята и задействована.
Elasticsearch также широко используется для поиска контента, анализа данных и запросов. Для получения дополнительной информации посетите сайты Haystack и Elasticsearch.
Автор: Esther Vaati
Источник: https://code.tutsplus.com
Редакция: Команда webformyself.