草垛
Haystack是一个Python库,可为Django提供模块化搜索。 它具有一个API,可为不同的搜索后端提供支持,例如Elasticsearch,Whoosh,Xapian和Solr。
弹性搜索
Elasticsearch是一种流行的Lucene搜索引擎,能够进行全文本搜索,它使用Java开发。
Google搜索使用与索引数据相同的方法,这就是为什么仅用几个关键字就可以很容易地检索任何信息的原因,如下所示。
安装Django Haystack和Elasticsearch
第一步是在您的计算机上本地启动和运行Elasticsearch。 Elasticsearch需要Java,因此您需要在计算机上安装Java。
我们将按照Elasticsearch网站上的说明进行操作。
下载Elasticsearch 1.4.5 tar,如下所示:
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"
}
确保您还安装了干草堆。
pip install django-haystack
让我们创建我们的Django项目。 我们的项目将能够为银行中的所有客户建立索引,从而仅需几个搜索字词就可以轻松地搜索和检索数据。
django-admin startproject Bank
该命令创建的文件为Django项目提供配置。
让我们为客户创建一个应用程序。
cd Bank
python manage.py startapp customers
settings.py
配置
为了使用Elasticsearch索引可搜索的内容,我们需要在项目的settings.py
文件中为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
,我们还将将干草堆和客户添加到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)
像这样在admin.py
注册您的Customer
模型:
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
对象是干草堆确定应在搜索索引中放置哪些数据并处理数据流的方式。要构建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
是在草堆的字段SearchIndex
防止不正确匹配时的两个不同的字的部分一起捣碎。
它允许我们使用autocomplete
功能进行查询。 当我们开始查询数据时,将使用自动完成功能。
document=True
表示要在其中进行搜索的主要字段。 另外, text
字段中的use_template=True
允许我们使用数据模板来构建将要建立索引的文档。
让我们在客户模板目录中创建模板。 在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来查询数据。
搜索模板
将干草堆网址添加到您的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
客户的结果。 如果没有客户的名字是Albert,那么查询将给出空结果。 随意使用自己的数据。
干草堆API
Haystack具有SearchQuerySet
类,该类旨在使执行搜索和迭代结果变得容易且一致。 大多数SearchQuerySet
API都熟悉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 file
定义的字段。
除了contains
字段查找之外,还有其他可用于执行查询的字段,包括:
- 内容
- 包含
- 精确
- gt
- te
- lt
- 升
- 在
- 以。。开始
- 以。。结束
- 范围
- 模糊
结论
在社交媒体,医疗保健,购物和其他行业的任何特定时刻,都会产生大量数据。 这些数据大部分都是非结构化和分散的。 Elasticsearch可用于将这些数据处理和分析成一种易于理解和使用的形式。
Elasticsearch还被广泛用于内容搜索,数据分析和查询。 有关更多信息,请访问Haystack和Elasticsearch网站。
翻译自: https://code.tutsplus.com/articles/how-to-index-and-query-data-with-haystack-and-elasticsearch-in-python--cms-29492