迁移指南:从 NEST v7 到 .NET 客户端 v8

编辑

迁移指南:从 NEST v7 到 .NET 客户端 v8

编辑

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

版本 8 是一次刷新

编辑

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

随着时间的推移,成熟的代码越来越难维护。主要版本允许我们简化,并在设计方面更好地将我们的语言客户端彼此对齐。在跨编程语言的统一性和每种语言的惯用问题之间找到适当的平衡至关重要。对于 .NET,我们通常会与 JavaGo 进行比较和对比,以确保我们的方法对于这些语言都是等效的。我们还从 Microsoft 框架设计指南和更广泛的 .NET 社区的惯例中汲取了大量灵感。

新的 Elastic.Clients.Elasticsearch NuGet 包

编辑

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

虽然这是一个新软件包,但我们已将主要版本(v8.x.x)与支持的 Elasticsearch 服务器版本对齐,以清楚地表明客户端/服务器的兼容性。v8 客户端设计为与 Elasticsearch 的版本 8 一起使用。

v7 NEST 客户端将继续获得支持,但不会获得新功能或对新 Elasticsearch 端点的支持。应考虑弃用它,而改用新客户端。

有限的功能集

编辑

版本 8 Elasticsearch .NET 客户端与之前的 v7 NEST 高级客户端不具有功能对等性。

如果缺少您依赖的功能(并且未在下面明确记录为我们不计划重新引入的功能),请打开 一个问题 或在相关的现有问题上发表评论,以向我们强调您的需求。这将帮助我们确定路线图的优先级。

代码生成

编辑

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

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

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 客户端的使用引入抽象,以此作为将使用代码与客户端类型分离并支持单元测试的首选方式。

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

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

除了我们现有对使用 InMemoryConnection、虚拟化集群和我们的 Elastic.Elasticsearch.Managed 库针对真实 Elasticsearch 实例进行集成测试的支持之外,这些更改是对其的补充。

迁移到 Elastic.Clients.Elasticsearch

编辑

版本 8 客户端目前不具备 NEST 的完整功能对等性。客户端的主要用例是供与 Elasticsearch 通信的应用程序开发人员使用。

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

选择代码生成 Elasticsearch .NET 客户端的新版本会引入一些重大的重大更改。

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

重大更改

编辑

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

我们努力保持核心基础的合理相似性,但是通过代码生成的类型在 NEST (v7) 和新的 Elastic.Clients.Elasticsearch (v8) 软件包之间可能会发生更改。

命名空间

编辑

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

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

类型名称

编辑

类型名称可能与之前的版本有所不同。由于可能存在大量细微差异,此处不再显式列出。类型名称现在将更紧密地与 JSON 中使用的名称以及 Elasticsearch 文档中记录的名称对齐。

类成员

编辑

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

密封类

编辑

在 .NET 生态系统中,关于“默认密封”的观点往往非常两极化。微软密封所有内部类型以获得潜在的性能提升,我们认为对于 Elasticsearch .NET 客户端(即使对于我们的公共 API 表面)也应该从这种方法开始,这样做是有益的。

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

已删除的功能

编辑

作为新客户端全新设计的一部分,v8.0 客户端中删除了某些功能。这些功能如下所示

属性映射
编辑

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

CAT API
编辑

Elasticsearch 的 CAT API 旨在供人阅读,并且不再通过 v8 Elasticsearch .NET 客户端支持。

接口删除
编辑

为了简化库并避免出现只需要单个接口实现的情况(例如 NEST 中的 IElasticClient),删除了一些接口。整个库中,抽象基类优先于接口,因为这样可以更轻松地添加增强功能,而不会为派生类型引入重大更改。

缺少的功能

编辑

以下是一些尚未为 v8 客户端重新实现的主要功能。未来版本可能会审查并优先考虑将它们包括在内。

  • 用于组合查询的查询 DSL 运算符。
  • 滚动助手。
  • 用于联合类型的 Fluent API。
  • 用于字段数据类型推断的 AutoMap
  • Properties 等类型的访问者模式支持。
  • 对影响 ChildrenAggregationJoinField 的支持。
  • 无条件查询。
  • 为了提供改进的诊断的全新开始,Elastic.Transport 中已删除 DiagnosticSources。Elasticsearch .NET 客户端会发出 OpenTelemetry 兼容的 Activity 跨度,APM 代理(如 适用于 .NET 的 Elastic APM 代理)可以使用这些跨度。
  • 文档正在编写中,我们将在未来版本中扩展已记录的场景。

减少的 API 表面

编辑

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

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

缺少功能的解决方法

编辑

如果您在使用 v8 客户端时遇到缺少的功能,有几种方法可以暂时解决此问题,直到我们正式重新引入该功能。

在 v8 Elasticsearch .NET 客户端的功能与应用程序要求保持一致之前,NEST 7.17.x 可以继续在与 Elasticsearch 8.x 服务器的兼容模式中使用。

作为最后的手段,可以使用底层客户端 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));