Elasticsearch:升级到 elasticsearch-py 8.x 的 10 个理由

作者:来自 Elastic 公司 Quentin_Pradet

早在 2022 年 2 月,当 Elasticsearch 8.0 发布时,Python 客户端也发布了 8.0 版本。 它是 7.x 客户端的部分重写,并附带了许多不错的功能(概述如下),但也有弃用警告和重大更改。 如今,7.17 版客户端仍然相对受欢迎,每月下载量超过 100 万次,约占 8.x 下载量的 50%

作为 Elasticsearch Python 客户端的新维护者,我希望我们的社区能够从我们在客户端中所做的改进中受益,通过帮助所有 elasticsearch-py 用户:

  • 帮助 7.17 用户迁移到 8.x,
  • 帮助 8.x 用户利用新功能。

根据我作为 urllib3 维护者的经验,我知道投资 urllib3 2.0 迁移指南 并帮助用户迁移是有回报的。 同样,我们现在正在努力通过删除弃用警告和重大更改来使 elasticsearch-py 8.x 更易于使用。 这篇文章重点介绍了升级到 8.x 的充分理由:这些理由在近两年内都是如此,但最近的理由也是如此。 顺便说一句,如果你已经确信,请查看我们的迁移指南(如果你遇到困难,请务必联系我们!):

Migrating to 8.0 | Elasticsearch Python Client [8.11] | Elastic

话不多说,以下是使用 elasticsearch-py 8.x 的十个理由。

  1. 支持最新的 Elasticsearch API

Elasticsearch 8 是 Elasticsearch 的最佳版本,全面进行了许多改进,并大大增加了可扩展性。更重要的是,对于我们对 Python 客户端的讨论,添加了各种新的 API:

由于客户端是根据 Elasticsearch 规范生成的,因此可以保证获得最新、最好的 API。

  1. Elasticsearch DSL 客户端 8.x

Elasticsearch DSL 客户端 是一个高级库,其目的是帮助以更简洁的方式编写和运行针对 Elasticsearch 的查询。 使用与之前文章相同的 christmas_characters 索引作为示例:

css 复制代码
1.  response = client.search(
2.      index="christmas_characters",
3.      query={
4.          "bool": {
5.              "must": [{"match": {"behavior": "good"}}]
6.          }
7.      }
8.  )

10.  for hit in response['hits']['hits']:
11.      print(hit['_score'], hit['_source']['title'])

变成:

ini 复制代码
1.  s = Search(using=client, index="christmas_characters").query("match", behavior="good")

3.  for hit in s.execute():
4.      print(hit.meta.score, hit.title)

你要么喜欢它的简洁性,要么讨厌学习新的 DSL,但这个客户端非常受欢迎,每月下载量超过 300 万次,并拥有专门的用户群。 它过去维护得很差,一直停留在 7.4.1 版本,但我在 9 月份发布了 8.9.0 版本,这是第一个与主要 Python 客户端版本 8 兼容的版本。

我致力于维护它,并于上个月发布了 8.11.0,以支持 Python 3.12 并允许折叠(collapsing queries)查询(相关 GitHub 问题已累积 38 票!)。

3. 种类型提示和更多 Pythonic API

从 Elasticsearch Python 客户端的早期(早在 2013 年 7 月起!)开始,body 参数就是为接受它的请求指定请求正文的方法。 使用 body 的 API 调用如下所示:

ini 复制代码
1.  es.search(
2.      index="christmas_characters",
3.      body={
4.          "query": {"match_all": {}},
5.          "size": 50,
6.      }
7.  )

然而,这个参数是一个无类型的 Python 字典,没有经过客户端验证,这意味着在将请求发送到服务器之前你无法判断你的请求是否正确。 但你不想了解生产中的基本问题! 因此,elasticsearch-py 8.0 利用 Elasticsearch 规范引入了更好的 API,该规范提供了每个 API 的完整类型。 第一层主体键可以使用 Python 参数指定:

ini 复制代码
1.  es.search(
2.      index="christmas_characters",
3.      query={"match_all": {}},
4.      size=50,
5.  )

这具有多种优点,包括更好的自动完成和类型检查。 例如,如果 size 不是整数,mypy 将引发错误。 因为我们意识到我们可以将 body unpack 为类型化参数,如下所示:

perl 复制代码
1.  es.search(
2.      index="christmas_characters",
3.      **{"query": {"match_all": {}}, "size": 50}
4.  )

我们决定在 elasticsearch-py 8.0 中完全弃用 body 参数。

  1. 恢复 body 参数

然而,弃用 body 有以下缺点:

  • 过去十年编写的许多代码现在都触发了弃用警告
  • 未知参数(例如 sub_searches 或 Elasticsearch 规范中的无意遗漏)被拒绝,导致查询彻底失败,不必要地强制使用原始请求。
  • 诸如传递已编码主体以避免支付序列化 JSON 成本之类的优化已不再可能。

客户端的原作者 Honza Král 指出了这些问题 ,我们决定让 body 与新 API 一起像以前一样工作,没有任何警告。 这将在 elasticsearch-py 8.12 中提供,我们希望这将有助于 elasticsearch-py 8.x 的采用。

  1. 记录调试请求

elasticsearch-py 8.x 客户端基于 elastic-transport 库,可以作为不同客户端的基础。 该库引入了一个非常有用的功能来调试请求和响应,通过调用 elastic_transport.debug_logging() 来启用。

css 复制代码
1.  import elastic_transport
2.  from elasticsearch import Elasticsearch

4.  # In this example we're debugging an Elasticsearch client:
5.  client = Elasticsearch(...)
6.  # Use `elastic_transport.debug_logging()` before the request
7.  elastic_transport.debug_logging()

9.  client.search(
10.      index="christmas_characters",
11.      query={
12.          "bool": {
13.              "must": [{"match": {"behavior": "good"}}]
14.          }
15.      }
16.  )

上述脚本将输出以下日志:

markdown 复制代码
1.  [2021-11-23T14:11:20] > POST /example-index/_search?typed_keys=true HTTP/1.1
2.  > Accept: application/json
3.  > Accept-Encoding: gzip
4.  > Authorization: Basic <hidden>
5.  > Connection: keep-alive
6.  > Content-Encoding: gzip
7.  > Content-Type: application/json
8.  > User-Agent: elastic-transport-python/8.11.0+dev
9.  > X-Elastic-Client-Meta: es=8.11.0p,py=3.12.0,t=8.11.0p,ur=2.1.0
10.  > {"query":{"match":{"text-field":"value"}}}
11.  < HTTP/1.1 200 OK
12.  < Content-Encoding: gzip
13.  < Content-Length: 165
14.  < Content-Type: application/json;charset=utf-8
15.  < Date: Tue, 12 Dec 2022 20:11:20 GMT
16.  < X-Cloud-Request-Id: ctSE59hPSCugrCPM4A2GUQ
17.  < X-Elastic-Product: Elasticsearch
18.  < X-Found-Handling-Cluster: 40c9b5837c8f4dd083f05eac950fd50c
19.  < X-Found-Handling-Instance: instance-0000000001
20.  < {"hits":{...}}

从我了解到这个功能的那天起,这个功能就成为了我开发工作流程的重要组成部分,现在我在其他客户端中怀念它:它就是那么好!

  1. 全链 SSL/TLS 指纹固定

当通过 HTTPS 与 Elasticsearch 通信时(这是从 Elasticsearch 8 开始的默认设置),客户端需要能够验证服务器正在使用的证书,就像你的浏览器在获取单词之前必须验证 discuss.elastic.co 的证书一样 您当前正在阅读。 这是通过跟踪证书链直至根证书颁发机构(根 CA)来实现的。 但是,该根 CA 不一定是已受信任的通用根 CA,而可能是整个公司使用的企业根 CA,甚至可能是 Elasticsearch 为单个集群生成的根 CA

在这些情况下,有两种方法可以正确验证证书:

  1. 将相关的证书颁发机构存储在文件中,并配置 ca_certs 参数。 然而,存储此文件需要额外的步骤,并且访问公共证书并不总是那么容易。
  2. 指定集群中每个节点的 SSL 指纹,以确保每个节点的证书永远不会改变。 但是,你需要为每个节点执行此操作,这对于较大的集群来说在实践中是不可能的。

值得庆幸的是,作为 Python 信任存储工作的一部分,前 Elasticsearch Python 客户端维护者 Seth Larson 意识到,使用 Python 3.10+ 私有 API ,可以固定根 CA 的指纹,从而允许验证所有节点的证书,从而带来 两全其美的。 请参阅配置| Elasticsearch Python 客户端 [8.11] | Elastic 适用于 Python 客户端中有关 TLS 的所有选项。

  1. options() API

在 elasticsearch-py 7.x中,客户端 API 方法中允许使用每个请求选项,例如 api_key 和 ignore。 然而,这很令人困惑,因为它混合了传输级参数和 API 级参数。 现在已弃用,因为 elasticsearch-py 8.x 引入了 options() API,转换:

ini 复制代码
client.search(index="christmas_characters", request_timeout=10)

为:

ini 复制代码
client.options(request_timeout=10).search(index="christmas_characters")

有关详细信息,请参阅迁移指南

  1. 改进文档

当前的主要焦点是改进 Python 客户端的文档。

API 参考按命名空间划分,以减少类似名称的 API(如 es.existses.indices.exists)之间的混淆。

它还包括内联类型提示

最后,添加了 快速入门交互式示例 页面。

9.无服务器 - serverless

Elastic 的最新产品 Serverless 有一个专用的 Elasticsearch Python 客户端 elasticsearch-serverless-python,其中仅包含 Serverless 支持的 API 和选项。

也就是说,默认的 Python 客户端 elasticsearch-py 也支持 Serverless,这使得你可以轻松地使用现有代码尝试 Serverless!

  1. 生成式人工智能

Elastic 在 Generative AI 方面投入了大量资金,Elasticsearch 是下载次数最多的向量数据库! 最好的入门方式是 Elastic Search Labs。它包含适用于 elasticsearch-py 8.x 的每个用例的博客文章和 Python 笔记本。

就是这样! 谢谢阅读。 当你准备好升级时,迁移指南是最好的起点。

Migrating to 8.0 | Elasticsearch Python Client [8.11] | Elastic

相关推荐
Elastic 中国社区官方博客3 小时前
使用 Elastic 收集 Windows 遥测数据:ETW Filebeat 输入简介
大数据·windows·elasticsearch·搜索引擎·全文检索·可用性测试
鸡c6 小时前
IM项目-----ElasticSearch
大数据·elasticsearch·搜索引擎
java1234_小锋8 小时前
在Elasticsearch中,是怎么根据一个词找到对应的倒排索引的?
大数据·elasticsearch·搜索引擎
java1234_小锋13 小时前
详细描述一下Elasticsearch搜索的过程?
大数据·elasticsearch·jenkins
gma99917 小时前
ES 基本使用与二次封装
大数据·数据库·c++·elasticsearch·搜索引擎
java1234_小锋1 天前
详细描述一下Elasticsearch索引文档的过程?
大数据·elasticsearch·搜索引擎
小黑屋说YYDS1 天前
ElasticSearch7.x入门教程之集群安装(一)
elasticsearch
Mephisto.java1 天前
【大数据学习 | Spark-Core】Spark的分区器(HashPartitioner和RangePartitioner)
大数据·elasticsearch·oracle·spark·sqlite·flume·memcached
衣舞晨风1 天前
[译]Elasticsearch Sequence ID实现思路及用途
elasticsearch·checkpoint·sequence·primaryterm
cab51 天前
聊一聊Elasticsearch的索引(1)
大数据·elasticsearch·搜索引擎