如何用Python中的Hay堆栈和Elasticearch对数据进行索引和查询
干草堆
haystack是一个Python库,它为Django提供模块化搜索。它具有一个API,它为不同的搜索后端提供支持,例如Elasticearch、Whosh、Xapian和Solr。
弹性搜索
ElasticSearch是一个流行的Lucene搜索引擎,能够进行全文搜索,它是用Java开发的。
Google搜索使用同样的方法来索引他们的数据,这就是为什么只要几个关键字就可以很容易地检索到任何信息的原因,如下所示。
[图片上传失败...(image-eccce5-1572571900366)]
安装Django Hay堆栈和Elasticearch
第一步是让ElasticSearch在您的机器上在本地运行。ElasticSearch需要Java,所以您需要在机器上安装Java。
我们将按照ElasticSearch网站.
下载Elasticsearch 1.4.5 tar,如下所示:
|
1
|
curl -L -O https:``//download``.elastic.co``/elasticsearch/elasticsearch/elasticsearch-1``.4.5.``tar``.gz
|
摘录如下:
|
1
|
tar -xvf elasticsearch-1.4.5.``tar``.gz
|
然后,它将在当前目录中创建一批文件和文件夹。然后进入bin目录,如下所示:
|
1
|
cd elasticsearch-1.4.5``/bin
|
启动Elasticearch,如下所示。
|
1
|
.``/elasticsearch
|
若要确认是否已成功安装,请转到http://127.0.0.1:9200/你应该看看这样的东西。
|
01
02
03
04
05
06
07
08
09
10
11
12
13
|
{
"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"
}
|
确保你也有干草堆安装。
|
1
|
pip ``install django-haystack
|
让我们创建Django项目。我们的项目将能够索引所有客户在一家银行,使它很容易搜索和检索数据只用几个搜索条件。
|
1
|
django-admin startproject Bank
|
此命令创建为Django项目提供配置的文件。
让我们为客户创建一个应用程序。
|
1
2
3
|
cd Bank
python manage.py startapp customers
|
settings.py配置
为了使用Elasticsearch索引我们可搜索的内容,我们需要在我们的项目中定义一个“大海捞针”的后端设置。settings.py档案。我们将使用ElasticSearch作为后端。
HAYSTACK_CONNECTIONS是必需的设置,应该如下所示:
|
1
2
3
4
5
6
7
|
HAYSTACK_CONNECTIONS ``= {
'default'``: {
'ENGINE'``:``'haystack.backends.elasticsearch_backend.ElasticsearchSearchEngine'``,
'URL'``: ``'[http://127.0.0.1:9200/](http://127.0.0.1:9200/)'``,
'INDEX_NAME'``: ``'haystack'``,
},
}
|
在settings.py,我们还将把干草堆和客户添加到installed apps.
|
01
02
03
04
05
06
07
08
09
10
11
|
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,添加以下代码。
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
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就像这样:
|
1
2
3
4
5
6
|
from django.contrib ``import admin
from .models ``import Customer
# Register your models here.
admin.site.register(Customer)
|
创建数据库和超级用户
应用您的迁移并创建一个管理帐户。
|
1
2
|
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在Customers应用程序目录中,并添加以下代码。
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
|
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指示用于在其中进行搜索的主字段。此外,use_template=True在text字段允许我们使用数据模板来生成将被索引的文档。
让我们在客户模板目录中创建模板。内search/indexes/customers/customers_text.txt,增加以下内容:
|
1
2
3
|
{{``object``.first_name}}
{{``object``.last_name}}
{{``object``.other_names}}
|
再索引数据
现在,我们的数据在数据库中,是时候把它放在我们的搜索索引中了。要做到这一点,只需运行./manage.py rebuild_index...您将得到处理和放置在索引中的模型总数。
|
1
|
Indexing 20 customers
|
或者,您可以使用RealtimeSignalProcessor,它会自动为您处理更新/删除。若要使用它,请在settings.py档案。
|
1
|
HAYSTACK_SIGNAL_PROCESSOR ``= 'haystack.signals.RealtimeSignalProcessor'
|
查询数据
我们将使用搜索模板和HaystackAPI来查询数据。
搜索模板
将干草URL添加到您的URLconf中。
|
1
|
url(r``'^search/'``, include(``'haystack.urls'``)),
|
让我们创建搜索模板。在……里面templates/search.html,添加以下代码。
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
|
{% block head %}
<``link rel``=``"stylesheet"``href``=``"[http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css](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](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](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.
完整的项目结构应该如下所示:
[图片上传失败...(image-a3566d-1572571900366)]
现在运行服务器,转到127.0.0.1:8000/search/,并进行如下所示的搜索。
[图片上传失败...(image-7c2aaa-1572571900366)]
搜索Albert将给出所有客户的姓名Albert...如果没有一个名为Albert的客户,那么查询将给出空的结果。随意使用自己的数据。
广告
干草堆API
干草堆SearchQuerySet类,该类的设计使执行搜索和迭代结果变得简单一致。大部分SearchQuerySetAPI熟悉Django的ORMQuerySet.
在……里面customers/views.py,添加以下代码:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
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 ``在……里面 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,我们使用的是含方法只检索包含定义字符的结果。例如,Al将只检索包含以下内容的客户的详细信息:Al...注意,结果将只来自在customer_text.txt file.
[图片上传失败...(image-c0cb8f-1572571900365)]
除了含字段查找,还有其他可用于执行查询的字段,包括:
- 含量
- 含
- 精确性
- 燃气轮机
- GTE
- 阿特
- LTE
- 在……里面
- 起家
- 端部
- 范围
- 模糊
结语
在社交媒体、健康、购物和其他部门,在任何特定时刻都会产生大量的数据。这些数据大部分是非结构化和分散的。ElasticSearch可以用来处理数据并将其分析成可以理解和使用的表单。









网友评论