Elasticsearch.Nest 教程系列 3-2 序列化:Extending NEST types | 扩展 NEST 类型

  • 本系列博文是“伪”官方文档翻译(更加本土化),并非完全将官方文档进行翻译,而是在查阅、测试原始文档并转换为自己真知灼见后的“准”翻译。有不同见解 / 说明不周的地方,还请海涵、不吝拍砖 :)

  • 官方文档见此:https://www.elastic.co/guide/en/elasticsearch/client/net-api/current/introduction.html

  • 本系列对应的版本环境:ElasticSearch@7.3.1,NEST@7.3.1,IDE 和开发平台默认为 VS2019,.NET CORE 2.1

NEST 的默认 JSON 序列化知道如何正确的序列化所有请求和响应类型,以及如何正确处理的你的 .NET 模型类。然而有的时候,你可能需要修改默认行为或者自定义你自己的序列化器,本章节将说明如何自定义以及扩展 NEST 类型。


有时为了解决某些问题,或者因为你使用了扩展了 Elasticsearch 功能的第三方插件,需要你提供某一种类型的自定义实现,而 NEST 并没有提供现成的支持。这个时候就可以通过如下方式来扩展 NEST 的类型使得在某些场景支持:

创建你自己的属性映射

通过实现自定义的 IProperty 实现,将 POCO 属性跟 NEST 字段进行映射。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class MyPluginProperty : IProperty
{
IDictionary<string, object> IProperty.LocalMetadata { get; set; }
public string Type { get; set; } = "my_plugin_property";
public PropertyName Name { get; set; }

public MyPluginProperty(string name, string language)
{
this.Name = name;
this.Language = language;
this.Numeric = true;
}

[PropertyName("language")]
public string Language { get; set; }

[PropertyName("numeric")]
public bool Numeric { get; set; }
}
  • PropertyNameAttribute 特性用于标记应序列化的属性。如果没有此属性,NEST将不会选择该属性进行序列化。

在创建索引的时候使用自定义的 IProperty 实现

1
2
3
4
5
6
7
var createIndexResponse = client.Indices.Create("myindex", c => c
.Map<Project>(m => m
.Properties(props => props
.Custom(new MyPluginProperty("fieldName", "dutch"))
)
)
);

序列化结果:

1
2
3
4
5
6
7
8
9
10
11
{
"mappings": {
"properties": {
"fieldName": {
"type": "my_plugin_property",
"language": "dutch",
"numeric": true
}
}
}
}

NEST 可以"序列化" my_plugin_property,但它不知道如何"反序列化"。NEST 团队将在未来将使这种方式更加可插拔。