设置 Elasticsearch Python 客户端

在本节中,您将安装用于 Python 的 Elasticsearch 客户端库,并使用它连接到 Elasticsearch 服务。

安装

Elasticsearch 客户端库是一个 Python 软件包,与pip 一起安装。确保先前创建的虚拟环境已激活,然后运行以下命令安装客户端:

pip install elasticsearch

为避免任何潜在的不兼容性,请确保您安装的 Elasticsearch 客户端库版本与您正在使用的 Elasticsearch 栈版本一致。

建议随时更新requirements.txt文件,以包含所有依赖项,因此现在是更新该文件以包含新安装软件包的好时机。在终端运行以下命令

pip freeze > requirements.txt

连接到 Elasticsearch

要创建与 Elasticsearch 服务的连接,必须使用适当的连接选项创建Elasticsearch 对象。

在代码编辑器中新建一个search.py文件,位于search-tutorial目录中。search.py文件将定义所有搜索函数。为搜索功能设置一个单独文件的目的是为了方便你以后提取该文件并将其添加到自己的项目中。

search.py中输入以下代码,添加一个Search 类:

import json
from pprint import pprint
import os
import time

from dotenv import load_dotenv
from elasticsearch import Elasticsearch

load_dotenv()


class Search:
    def __init__(self):
        self.es = Elasticsearch()  # <-- connection options need to be added here
        client_info = self.es.info()
        print('Connected to Elasticsearch!')
        pprint(client_info.body)

这里有很多东西需要解读。导入后调用的load_dotenv() 函数来自python-dotenv软件包。该软件包知道如何使用.env文件,用于存储密码和密钥等配置变量。load_dotenv() 函数读取存储在.env文件,并将它们作为环境变量导入 Python 进程。

Search 类有一个构造函数,用于创建Elasticsearch 客户端类的实例。这是所有与 Elasticsearch 服务通信的客户端逻辑所在。请注意,这一行目前还不完整,因为还需要包括适合您的服务的连接选项。您将在下文中了解到哪些方案适用于您的情况。创建Elasticsearch 对象后,该对象就会存储在名为self.es 的实例变量中。

为确保客户端对象能与 Elastic Cloud 部署通信,会调用info() 方法。该方法调用服务,请求提供基本信息。如果调用成功,则可以认为与服务的连接有效。

然后,该方法会打印一条状态信息,表明连接已建立,然后使用 Python 的pprint 函数,以易于阅读的格式显示服务返回的信息。

注意: 您可能已经注意到,该文件导入了 Python 标准库中的 json 包,但并未使用。请勿删除此导入,因为稍后将使用此软件包。

要完成Search 类的构造函数,需要为Elasticsearch 对象提供适当的连接选项。下面的小节将介绍弹性云和 Docker 安装方法所需的选项。

连接到弹性云部署

如果您按照说明创建了 Elastic Cloud 部署,则需要知道部署的云 ID 和 API 密钥。由于这些都是敏感值,因此不宜直接将它们写入应用程序代码中。而不是创建一个.env(发音为 dot-env)文件,这些机密可以安全地存储在其中。

打开你喜欢的代码编辑器,在search-tutorial项目目录下新建一个文件,文件名为.env(别忘了前面的点)。在该文件中输入以下内容

ELASTIC_CLOUD_ID="paste your Cloud ID here"
ELASTIC_API_KEY="paste your API Key here"

注意:如果计划将此项目提交到源代码控制库,应确保不包含.env文件,以防止你的 Elastic 账户凭据被泄露。

如果使用 git,请在.gitignore末尾添加以下一行文件(如果还没有,则创建一个新文件):

.env文件中输入凭据后文件中的Search 类构造函数,并将第一行编辑如下:

class Search:
    def __init__(self):
        self.es = Elasticsearch(cloud_id=os.environ['ELASTIC_CLOUD_ID'],
                                api_key=os.environ['ELASTIC_API_KEY'])
        # ...

cloud_idapi_key 参数的值是从环境中提取的,Python 将其保存在os.environ 字典中。这些变量从.env文件,并通过load_dotenv() 函数存储在该字典中。

连接到自托管的 Elasticsearch Docker 容器

如果您选择使用 Docker运行本地托管的 Elasticsearch 服务,那么唯一需要的连接选项就是连接端点。编辑search.pySearch 类构造函数的第一行如下:

class Search:
    def __init__(self):
        self.es = Elasticsearch('http://localhost:9200')
        # ...

在此版本的构造函数中,Elasticsearch 对象是通过 Elasticsearch 服务顶级端点的 URL 实例化的,该端点通常是http://localhost:9200。请注意,Docker说明明确禁止加密和身份验证,因此无需提供任何凭证。

测试连接

此时,您就可以与 Elasticsearch 服务建立连接了。为此,请确保已激活 Python 虚拟环境,然后键入python 启动 Python 交互会话。您会看到熟悉的>>> 提示符,可以在其中输入 Python 语句。

导入Search 类的方法如下

from search import Search

接下来,实例化新类:

es = Search()

您应该会看到一条连接信息,随后是客户端info() 方法返回的信息。除标识符和版本号不同外,输出结果应如下所示:

Connected to Elasticsearch!
{'cluster_name': 'ad552eba959043158be67dfc021e91cdc',
 'cluster_uuid': 'ks_HfcCdSf2adeKQEsk9gL',
 'name': 'instance-0000000000',
 'tagline': 'You Know, for Search',
 'version': {'build_date': '2023-11-04T10:04:57.184859352Z',
             'build_flavor': 'default',
             'build_hash': 'b4a62ac808e886ff032700c391f45f1408b2538c',
             'build_snapshot': False,
             'build_type': 'docker',
             'lucene_version': '9.7.0',
             'minimum_index_compatibility_version': '7.0.0',
             'minimum_wire_compatibility_version': '7.17.0',
             'number': '8.13.0'}}

如果出现错误,请确保在.env文件中输入了正确的凭据。如果您使用的是 Elastic Cloud 部署,或者是自托管部署,则需要按照说明在计算机中运行 Elasticsearch Docker 容器。

将 Elasticsearch 与 Flask 应用程序集成

本节的最后一步是将目前完成的工作集成到您之前安装的 Flask 小程序中。目标是让应用程序在启动时自动创建与 Elasticsearch 的连接。

为此,请在代码编辑器中打开app.py。在仅有的导入下面为search.py模块添加导入语句:

from search import Search

然后找到创建app 变量的那一行,紧接着创建新的Search 类的实例:

es = Search()

就是这样!现在,应用程序有了一个es 对象,可以在需要时使用。如果您仍在终端中运行 Flask 应用程序,那么在保存文件后,您应该会看到应用程序重新加载。重新加载后,Search 类构造函数打印的连接信息应该会出现,而且以后每次重启应用程序时都会继续出现。

如果您没有运行 Flask 应用程序,现在是启动它的好时机。在终端窗口中切换到项目目录,激活 Python 虚拟环境,然后用以下命令启动应用程序:

flask run

为帮助您在遇到错误时排除故障,下面是带有集成 Elasticsearch 客户端的app.py的完整副本:

import re
from flask import Flask, render_template, request
from search import Search

app = Flask(__name__)
es = Search()


@app.get('/')
def index():
    return render_template('index.html')


@app.post('/')
def handle_search():
    query = request.form.get('query', '')
    return render_template(
        'index.html', query=query, results=[], from_=0, total=0)


@app.get('/document/<id>')
def get_document(id):
    return 'Document not found'

准备好打造最先进的搜索体验了吗?

足够先进的搜索不是一个人的努力就能实现的。Elasticsearch 由数据科学家、ML 操作员、工程师以及更多和您一样对搜索充满热情的人提供支持。让我们联系起来,共同打造神奇的搜索体验,让您获得想要的结果。

亲自试用