迁移指南:从 NEST v7 迁移到 .NET Client v8

编辑

迁移指南:从 NEST v7 迁移到 .NET Client v8

编辑

以下迁移指南解释了客户端的当前状态、缺失的功能、重大更改以及我们对引入的一些设计选择的理由。

8.0 版本是全新改版

编辑

需要强调的是,Elasticsearch .NET Client 的 v8 版本代表了客户端设计的新起点。务必检查这可能会如何影响您的代码和使用方式。

随着时间的推移,成熟的代码越来越难以维护。主要版本允许我们简化并更好地使我们的语言客户端在设计方面彼此协调一致。在跨编程语言的统一性和每种语言的惯用关注点之间找到正确的平衡至关重要。对于 .NET,我们通常会与 JavaGo 进行比较和对比,以确保我们的方法对这些语言都是等效的。我们也大量借鉴了 Microsoft 框架设计指南和更广泛的 .NET 社区的约定。

新的 Elastic.Clients.Elasticsearch NuGet 包

编辑

我们将新的代码生成的客户端作为 NuGet 包 发布,并使用新的根命名空间 Elastic.Clients.Elasticsearch。v8 客户端建立在 v7 NEST 客户端的基础之上,但存在一些更改。通过将其作为新的包发布,预期可以采用分阶段的方法来管理迁移。

虽然这是一个新的包,但我们将主版本 (v8.x.x) 与受支持的 Elasticsearch 服务器版本对齐,以清楚地指示客户端/服务器兼容性。v8 客户端旨在与 Elasticsearch 8.0 版本一起使用。

v7 NEST 客户端将继续受到支持,但不会获得新功能或对新的 Elasticsearch 端点的支持。它应该被认为已弃用,应该优先使用新的客户端。

有限的功能集

编辑

8.0 版 Elasticsearch .NET Client 并不具备之前的 v7 NEST 高级客户端的全部功能。

如果您依赖的功能缺失(并且在下面没有明确记录为我们不打算重新引入的功能),请打开 一个问题 或评论相关的现有问题,以突出您的需求。这将有助于我们确定路线图的优先级。

代码生成

编辑

鉴于当今 Elasticsearch API 表面的规模,手动维护数千种类型(请求、响应、查询、聚合等)已不再切实可行。为确保语言客户端和 Elasticsearch 之间的一致性、准确性和及时对齐,8.x 客户端和许多相关的类型现在是从 共享规范 自动生成的。这是在 SDK 和库(例如 Azure、AWS 和 Google Cloud Platform 的 SDK 和库)之间维护客户端和服务器对齐的常见解决方案。

从规范进行代码生成不可避免地导致现有 v7 NEST 类型与新的 v7 Elasticsearch .NET Client 中提供的类型之间存在一些差异。对于 8.0 版本,我们严格地根据规范进行生成,在少数几个区域进行特殊处理以提高可用性或与语言习惯用法保持一致。

诸如 PropertiesAggregationsQueries 等概念的基本类型层次结构不再存在于生成的代码中,因为这些任意分组与公共服务器 API 的具体概念不一致。这些考虑因素并不排除在将来的版本中根据具体情况为类型添加语法糖和可用性增强功能。

Elastic.Transport

编辑

.NET 客户端包含一个传输层,负责抽象 HTTP 概念并提供诸如我们的请求管道之类的功能。这支持对节点的请求进行轮循负载均衡、对失败的节点进行 ping 操作以及嗅探集群的节点角色。

在 v7 中,此层作为 Elasticsearch.Net 发布,并被认为是我们的低级客户端,可用于在客户端和服务器之间发送和接收原始 JSON 字节。

作为 8.0.0 工作的一部分,我们将传输层移到了一个 新的专用包存储库 中,名为 Elastic.Transport。这支持在未来的客户端中重复使用,并允许具有极高性能要求的使用者在此基础上进行构建。

使用 System.Text.Json 进行序列化

编辑

v7 NEST 高级客户端使用了 Utf8Json 的内部化和修改版本用于请求和响应序列化。引入它是为了提高其相对于 Json.NET(当时更常见的 JSON 框架)的性能。

虽然 Utf8Json 提供了良好的价值,但我们发现了一些需要随时间推移进行维护的微小错误和性能问题。其中一些很难在没有更多努力的情况下进行更改。此库不再维护,任何此类更改都不能轻松地贡献回原始项目。

借助 .NET Core 3.0,Microsoft 发布了新的 System.Text.Json API,这些 API 包含在当前版本的 .NET 中。我们已将 System.Text.Json 用于所有序列化。如果使用者更喜欢使用其他序列化库,他们仍然可以定义和注册他们自己的 Serializer 实现以用于其文档类型。

通过采用 System.Text.Json,我们现在依赖于 Microsoft 提供的维护良好且受支持的库。System.Text.Json 从一开始就设计为支持 .NET 中最新的性能优化,因此可以提供快速且低分配的序列化。

ElasticsearchClient 的模拟性

编辑

测试代码是软件开发的重要组成部分。我们建议使用者更倾向于为他们对 Elasticsearch .NET Client 的使用引入一个抽象,作为将使用者代码与客户端类型解耦并支持单元测试的首选方法。

为了支持用户测试场景,我们取消密封了 ElasticsearchClient 类型并将其方法设为虚方法。这支持直接模拟该类型以进行单元测试。这比 NEST (v7) 中原始的 IElasticClient 接口(只支持模拟顶级客户端方法)有所改进。

我们还在 Elastic.Transport 中引入了一个 TestableResponseFactory,以便更容易创建具有特定状态代码和有效性的响应实例,这些实例可在单元测试期间使用。

这些更改是对我们现有支持使用 InMemoryConnection、虚拟化集群以及我们的 Elastic.Elasticsearch.Managed 库针对实际 Elasticsearch 实例进行集成测试的支持的补充。

迁移到 Elastic.Clients.Elasticsearch

编辑

8.0 版本的客户端目前不具备与 NEST 完全相同的功能。客户端的主要用例是与 Elasticsearch 通信的应用程序开发人员。

8.0 版本的客户端侧重于核心端点,更具体地说,是针对常见的 CRUD 场景。目的是在后续版本中减少功能差距。在从 v7 NEST 客户端迁移之前,请仔细阅读本文档,了解缺失的功能和简化的 API 表面详细信息!

选择对 Elasticsearch .NET Client 的新版本进行代码生成引入了一些重大的重大更改。

v8 客户端作为新的 NuGet 包 发布,可以与 v7 NEST 一起安装。某些使用者可能更喜欢在短时间内并排使用这两个包的分阶段迁移,以管理复杂的迁移。此外,NEST 7.17.x 可以继续在 兼容模式 下与 Elasticsearch 8.x 服务器一起使用,直到 v8 Elasticsearch .NET Client 的功能与应用程序需求一致。

重大更改

编辑

由于对大多数客户端类型进行了代码生成,因此客户端的 8.0 版本包含多个重大更改。

我们努力使核心基础保持相当相似,但通过代码生成的类型在 NEST (v7) 和新的 Elastic.Clients.Elasticsearch (v8) 包之间可能会发生变化。

命名空间

编辑

v8 客户端的包和顶级命名空间已重命名为 Elastic.Clients.Elasticsearch。所有类型都属于此命名空间。必要时,为避免潜在冲突,将根据 Elasticsearch 规范 将类型生成到合适的子命名空间中。使用 Elasticsearch .NET Client 时,可能需要额外的 using 指令来访问此类类型。

传输层概念已移至新的 Elastic.Transport NuGet 包,相关类型在其命名空间下定义。某些配置和低级传输功能可能需要 Elastic.Transport 命名空间的 using 指令。

类型名称

编辑

类型名称可能已更改为以前的版本。由于可能存在大量细微差异,因此未明确列出这些差异。类型名称现在将更紧密地与 JSON 中使用的名称以及 Elasticsearch 文档中记录的名称一致。

类成员

编辑

类型可能包含根据 Elasticsearch 规范重命名的属性,这些属性与原始 NEST 属性名称不同。由于代码生成,用于属性的类型也可能已更改。如果您发现缺少或类型不正确的属性,请打开 一个问题 以告知我们。

密封类

编辑

关于 .NET 生态系统中“默认密封”的观点往往非常两极分化。Microsoft 密封所有内部类型以获得潜在的性能提升,我们认为从 Elasticsearch .NET Client 的这种方法开始是有益的,即使是对于我们的公共 API 表面也是如此。

虽然它会阻止继承,因此可能会抑制一些使用者场景,但默认密封旨在避免意外或无效的类型扩展,这些扩展在将来可能会意外中断。

已删除的功能

编辑

作为新客户端的全新设计的组成部分,某些功能已从 v8.0 客户端中删除。这些功能列在下面。

属性映射
编辑

在早期版本的 NEST 客户端中,可以使用属性来配置用户类型的映射行为和推断。建议在配置客户端实例时,通过流畅 API 来完成映射。System.Text.Json 属性可用于在源序列化期间重命名和忽略属性。

CAT API
编辑

Elasticsearch 的 CAT API 旨在用于人类可读的使用,并且在 v8 Elasticsearch .NET 客户端中将不再支持。

接口移除
编辑

为了简化库并避免只期望存在单个实现的接口(例如 NEST 中的 IElasticClient),移除了几个接口。整个库更倾向于使用抽象基类而不是接口,因为这样可以更容易地添加增强功能,而不会为派生类型引入重大更改。

缺失的功能

编辑

以下是一些尚未为 v8 客户端重新实现的主要功能。这些功能可能会在将来的版本中进行审查并确定优先级。

  • 用于组合查询的查询 DSL 运算符。
  • 滚动辅助程序 (Scroll Helper)。
  • 联合类型的流畅 API。
  • AutoMap 用于字段数据类型推断。
  • Properties 等类型的访问者模式支持。
  • 对影响 ChildrenAggregationJoinField 的支持。
  • 无条件查询。
  • Elastic.Transport 中已移除 DiagnosticSources,以便为改进的诊断方案提供一个干净的基础。Elasticsearch .NET 客户端会发出与 OpenTelemetry 兼容的 Activity span,这些 span 可以被 APM 代理(例如 .NET 版 Elastic APM 代理)使用。
  • 文档正在开发中,我们将在将来的版本中扩展已记录的场景。

精简的 API 表面

编辑

在当前版本的代码生成的 .NET 客户端中,支持常用端点至关重要。某些特定查询和聚合需要进一步的工作才能正确生成代码,因此尚未包含它们。在迁移之前,请确保您正在使用的功能目前受支持。

所有受支持和不受支持端点的最新列表可以在 GitHub 上找到。

缺失功能的解决方法

编辑

如果您在 v8 客户端中遇到缺失的功能,则可以在我们正式重新引入该功能之前,通过几种方法暂时解决此问题。

兼容模式下,可以继续使用 NEST 7.17.x 与 Elasticsearch 8.x 服务器配合使用,直到 v8 Elasticsearch .NET 客户端的功能与应用程序需求相符。

作为最后手段,可以使用低级别客户端 Elastic.Transport 手动创建任何所需的请求。

var body = """
	{
	  "name": "my-api-key",
	  "expiration": "1d",
	  "...": "..."
	}
	""";

var response = await client.Transport.RequestAsync<StringResponse>(HttpMethod.POST, "/_security/api_key", PostData.String(body));