第15篇-使用Django进行ElasticSearch的简单方法

我的Elasticsearch系列文章,逐渐更新中,欢迎关注
0A.关于Elasticsearch及实例应用
00.Solr与ElasticSearch对比
01.ElasticSearch能做什么?
02.Elastic Stack功能介绍
03.如何安装与设置Elasticsearch API
04.如果通过elasticsearch的head插件建立索引_CRUD操作
05.Elasticsearch多个实例和head plugin使用介绍

06.当Elasticsearch进行文档索引时,它是怎样工作的?

07.Elasticsearch中的映射方式—简洁版教程

08.Elasticsearch中的分析和分析器应用方式

09. Elasticsearch中构建自定义分析器

10.Kibana科普-作为Elasticsearhc开发工具
11.Elasticsearch查询方法

12.Elasticsearch全文查询

13.Elasticsearch查询-术语级查询

14.Python中的Elasticsearch入门

15.使用Django进行ElasticSearch的简单方法

16.关于Elasticsearch的6件不太明显的事情
17.使用Python的初学者Elasticsearch教程
18.用ElasticSearch索引MongoDB,一个简单的自动完成索引项目
19.Kibana对Elasticsearch的实用介绍
20.不和谐如何索引数十亿条消息
21.使用Django进行ElasticSearch的简单方法

另外Elasticsearch入门,我强烈推荐ElasticSearch新手搭建手册和这篇优秀的REST API设计指南 给你,这两个指南都是非常想尽的入门手册。

 

 

前一段时间,我在Django项目上工作,想实现快速的自由文本搜索。我决定使用NoSQL数据库,而不是使用常规数据库来执行此搜索功能(例如MySQL或PostgreSQL)。那就是我发现ElasticSearch的时候。

ElasticSearch为您的数据索引文档,而不是像常规关系数据库那样使用数据表。这样可以加快搜索速度,并提供其他常规数据库无法获得的其他好处。我还保留了一个常规的关系数据库,用于存储用户详细信息,登录名和其他不需要ElasticSearch索引的数据。

在搜索了如何使用Django正确实现ElasticSearch的很长时间之后,我并没有真正找到令人满意的答案。似乎正在采取不必要的步骤来将数据索引到ElasticSearch中。有关如何执行搜索的信息很多,但有关如何完成索引的信息却不多。我觉得那里肯定有一个更简单的解决方案,所以我决定自己尝试一下。

我想使它尽可能简单,因为在我看来,简单的解决方案往往是最好的解决方案。KISS(保持简单愚蠢),少即是多,所有这些东西都引起了我的共鸣,特别是当其他解决方案非常复杂时。我决定在本视频中使用HonzaKrál的示例来为我的代码提供基础。我建议您观看它,尽管此时它有点过时了。

由于我使用的是用Python编写的Django,因此与ElasticSearch进行交互非常容易。有两个客户端库可通过Python与ElasticSearch进行交互。有elasticsearch-py,这是官方的低级客户端。还有elasticsearch-dsl,它是在前者的基础上构建的,但是它提供了更高层次的抽象,但功能却有所减少。

我们将很快讨论一些示例,但是首先我需要阐明我们要完成的工作:
● 在我们的本地计算机上设置ElasticSearch并确保其正常运行
● 设置一个新的Django项目
● 批量索引数据库中已经存在的数据
● 用户保存到数据库的每个新实例的索引
● 基本搜索示例

好吧,这似乎很简单。让我们开始在我们的机器上安装ElasticSearch。另外,所有代码都将在我的GitHub上可用,因此您可以轻松地遵循示例。
安装ElasticSearch
由于ElasticSearch在Java上运行,因此必须确保您具有更新的JVM版本。检查
java -version

终端中的版本。然后运行以下命令来创建新目录,下载,解压缩并启动ElasticSearch:

mkdir elasticsearch-examplewget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-5.1.1.tar.gztar -xzf elasticsearch-5.1.1.tar.gz./elasticsearch-5.1.1/bin/elasticsearch

当ElasticSearch启动时,应该在终端窗口上打印很多输出。要检查其启动和运行是否正确,请打开一个新的终端窗口并运行以下
curl

命令:
curl -XGET http:// localhost:9200

响应应该是这样的:

{ 
  name”:“ 6xIrzqq”,
  cluster_name ”:“ elasticsearch”,“ cluster_uuid”:“ 
  eUH9REKyQOy4RKPzkuRI1g”,
  version”:{ 
    number”:“ 5.1.1”,
    build_hash”:“ 5395e21”,
    build_date “:” 2016-12-06T12:36:15.409Z“,
    build_snapshot“:否,
    lucene_version“:” 6.3.0},

”标语“:”您知道,要搜索“太好了,您现在已经在本地计算机上运行了ElasticSearch!现在该设置您的Django项目了。
设置Django项目
首先,您要使用创建一个虚拟环境,
virtualenv venv

然后使用进行输入,
source venv/bin/activate

以保留所有内容。然后安装一些软件包:

pip install django 
pip install elasticsearch-dsl要启动一个新的Django项目,请运行:
django-admin startproject elasticsearchproject 
cd 
elasticsearchproject python manage.py startapp elasticsearchapp

创建新的Django项目后,您需要创建一个将要使用的模型。对于本指南,我选择了一个很好的老式博客文章示例。在其中
models.py

放置以下代码:

from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User
Create your models here.
Blogpost to be indexed into ElasticSearch
class BlogPost(models.Model):
   author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='blogpost')
   posted_date = models.DateField(default=timezone.now)
   title = models.CharField(max_length=200)
   text = models.TextField(max_length=1000)

到目前为止,还挺简单的。不要忘记添加
elasticsearchapp


INSTALLED_APPS


settings.py

和注册新的博文模型
admin.py

是这样的:

from django.contrib import admin
from .models import BlogPost
Register your models here.
Need to register my BlogPost so it shows up in the admin
admin.site.register(BlogPost)

您还必须
python manage.py makemigrations,python manage.py migrate


python manage.py createsuperuser

创建数据库和管理员帐户。现在,
python manage.py runserver

转到
http://localhost:8000/admin/

并登录。现在,您应该可以在那里看到您的Blog帖子模型。继续并在管理员中创建您的第一篇博客文章。
恭喜,您现在有了一个可正常运行的Django项目!终于是时候玩有趣的东西了–连接ElasticSearch。
将ElasticSearch与Django连接
首先,
search.py

在我们的
elasticsearchapp

目录中创建一个新文件。这是ElasticSearch代码的所在地。您在这里要做的第一件事是创建从Django应用程序到ElasticSearch的连接。您可以在
search.py

文件中执行此操作:
从 elasticsearch_dsl.connections 导入连接

connections.create_connection()

现在,您已经与ElasticSearch设置建立了全局连接,您需要定义要索引到其中的内容。编写这段代码:

from elasticsearch_dsl.connections import connections
connections.create_connection()
from elasticsearch_dsl.connections import connections
from elasticsearch_dsl import DocType, Text, Date
connections.create_connection()
class BlogPostIndex(DocType):
    author = Text()
    posted_date = Date()
    title = Text()
    text = Text()

    class Meta:
        index = 'blogpost-index'

它看起来与您的模型非常相似,对吧?该
DocType

作品的包装,让你写一个指数就像一个模型,并
Text


Date

各字段,以便他们得到正确的格式,当他们得到索引。
在Meta内部,您告诉ElasticSearch您希望索引被命名为什么。这将是ElasticSearch的参考点,以便当在数据库中初始化索引并保存每个创建的新对象实例时,它知道要处理的索引。
现在,您需要实际创建
BlogPostIndex

在ElasticSearch中新创建的映射。您可以执行此操作,还可以创建一种同时进行批量索引的方法-多么方便?
数据批量索引

bulk

命令位于该库的顶部,因此
elasticsearch.helpers

安装时包含该命令
elasticsearch_dsl

。在中执行以下操作

from elasticsearch.helpers import bulk
from elasticsearch import Elasticsearch
from . import models
......
def bulk_indexing(): 
BlogPostIndex.init()
es = Elasticsearch()
    bulk(client=es, actions=(b.indexing() for b in models.BlogPost.objects.all().iterator()))

“这里发生了什么?” 你可能在想。实际上,它并不那么复杂。
因为只要在我们的模型中进行某些更改,您就只想进行批量索引
init()

编制,因此可以将其映射到ElasticSearch中的模型。然后,您使用
bulk

并将其传递给实例,
Elasticsearch()

该实例将创建与ElasticSearch的连接。然后,您将生成器传递给常规数据库中
actions=

所有
BlogPost

对象并对其进行迭代,并
.indexing()

在每个对象上调用方法。为什么要使用发电机?因为如果要在生成器上迭代的对象很多,则不必先将它们加载到内存中。
上面的代码只有一个问题。您
.indexing()

的模型上还没有方法。让我们修复一下:

#将索引方法添加到

BlogPost 
def indexing(self):
   obj = BlogPostIndex(
      meta = { 'id':self.id},
      author = self.author.username,
      posted_date = self.posted_date,
      title = self.title ,
      text = self.text 
   )
   obj.save()

返回 obj.to_dict(include_meta = True)您将索引方法添加到
BlogPost

模型。它返回a
BlogPostIndex

并保存到ElasticSearch。
现在让我们尝试一下,看看是否可以对以前创建的博客文章进行批量索引。通过运行,
python manage.py shell

您进入Django shell并使用导入您
search.py


from elasticsearchapp.search import *

,然后运行
bulk_indexing()

以索引数据库中的所有博客文章。要查看它是否起作用,请运行以下curl命令:
curl -XGET'localhost:9200 / blogpost-index / blog_post_index / 1?pretty'您应该在终端上找回第一篇博客文章。
索引新保存的实例
接下来,您需要添加一个信号,以
.indexing()

在用户每次保存新博客帖子时保存的每个新实例上触发。在
elasticsearchapp

创建一个名为的新文件
signals.py

并添加以下代码:
从 .models 导入博文
从 django.db.models.signals 进口 post_save
从 django.dispatch 进口接收机

@receiver(post_save,发件人=博客帖子)
DEF index_post(发件人,例如,** kwargs):

instance.indexing()该

post_save

信号将确保保存的实例在保存后将与该
.indexing()

方法建立索引。
为了使它起作用,我们还需要注册我们正在使用信号的Django。我们首先打开
apps.py

并添加以下代码:
从django.apps导入AppConfig

类ElasticsearchappConfig(AppConfig):

name =' elasticsearchapp'def 

ready(self):
    import elasticsearchapp.signals

要完成此操作,我们还需要告诉Django我们正在使用此新配置。我们通过添加以下内容
__init__.py


elasticsearchapp

目录内部执行此操作:
default_app_config ='elasticsearchapp.apps.ElasticsearchappConfig'现在,该

post_save

信号已在Django中注册,并且随时可以在保存新博客文章时收听。
再次进入Django管理员并保存一个新博客,尝试一下。然后使用
curl

命令检查它是否已成功索引到ElasticSearch中。
简单搜索
现在让我们做一个简单的搜索功能
search.py

来查找按作者过滤的所有帖子:

从 elasticsearch_dsl 导入 DocType,文本,日期,搜索
......
def search(author):

s = Search()。filter('term',author = author)
response = s.execute()
返回响应让我们尝试搜索。在shell中:

from elasticsearchapp.search import *

并运行
print(search(author="<author name>"))

print(search(author="home"))
<Response: [<Result(blogpost-index/blog_post_index/1): {'text': 'Hello world, this is my first blog post', 'title':...}>]>

你有它!现在,您已成功将所有实例索引到ElasticSearch中,创建了一个
post_save

对每个新保存的实例进行索引的信号,并创建了一个函数来搜索我们的ElasticSearch数据库中的数据。

结论
这是一篇篇幅很长的文章,但我希望它写得足够​​简单,即使是初学者也能理解。

我解释了如何将Django模型连接到ElasticSearch进行索引和搜索,但是ElasticSearch可以做很多事情。我建议在他们的网站上阅读并探索还有哪些其他可能性,例如空间操作和带有智能突出显示的全文本搜索。它是一个很棒的工具,我一定会在以后的项目中使用它!
如果您喜欢本文或有任何评论或建议,请随时在下面留言。敬请期待更多有趣的东西!

posted @ 2020-06-17 21:54  普通人刘大  阅读(1385)  评论(0编辑  收藏  举报