如何用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
类,该类的设计使执行搜索和迭代结果变得简单一致。大部分SearchQuerySet
API熟悉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可以用来处理数据并将其分析成可以理解和使用的表单。
网友评论