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

相关推荐
hengzhepa23 分钟前
ElasticSearch备考 -- Search across cluster
学习·elasticsearch·搜索引擎·全文检索·es
Elastic 中国社区官方博客2 小时前
Elasticsearch:使用 LLM 实现传统搜索自动化
大数据·人工智能·elasticsearch·搜索引擎·ai·自动化·全文检索
慕雪华年3 小时前
【WSL】wsl中ubuntu无法通过useradd添加用户
linux·ubuntu·elasticsearch
Elastic 中国社区官方博客5 小时前
使用 Vertex AI Gemini 模型和 Elasticsearch Playground 快速创建 RAG 应用程序
大数据·人工智能·elasticsearch·搜索引擎·全文检索
alfiy6 小时前
Elasticsearch学习笔记(四) Elasticsearch集群安全配置一
笔记·学习·elasticsearch
alfiy7 小时前
Elasticsearch学习笔记(五)Elastic stack安全配置二
笔记·学习·elasticsearch
丶21361 天前
【大数据】Elasticsearch 实战应用总结
大数据·elasticsearch·搜索引擎
闲人编程1 天前
elasticsearch实战应用
大数据·python·elasticsearch·实战应用
世俗ˊ1 天前
Elasticsearch学习笔记(3)
笔记·学习·elasticsearch
weixin_466286681 天前
ElasticSearch入门
大数据·elasticsearch·搜索引擎