Elasticsearch.Nest 教程系列 4-6 映射:Ignoring properties | 映射时忽略 POCO 上的某些属性

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

  • 官方文档见此: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


POCO 类属性进行映射时,可以通过以下几种方式忽略部分属性

  • 在使用继承了 ElasticsearchPropertyAttributeBase 的各特性上使用 Ignore 属性:如在使用 TextAttribute 时,使用 Ingore 属性进行属性忽略。

  • 在使用 PropertyNameAttribute 的时候使用Ignore属性。

  • 使用 ConnectionSettings.DefaultMappingFor(Func<ClrTypeMappingDescriptor,
    IClrTypeMapping> selector) 方法的时候进行指定需要忽略的属性。

  • 使用能够被 IElasticsearchSerializer 识别的 Ignore 特性,内建的 SourceSerializer 可以使用 [IgnoreAttribute] 进行忽略。

忽略类中的部分属性

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[ElasticsearchType(RelationName = "company")]
public class CompanyWithAttributesAndPropertiesToIgnore
{
public string Name { get; set; }

[Text(Ignore = true)]
public string PropertyToIgnore { get; set; }

[PropertyName("anotherPropertyToIgnore", Ignore = true)]
public string AnotherPropertyToIgnore { get; set; }

public string FluentMappingPropertyToIgnore { get; set; }

[Ignore, JsonIgnore]
public string JsonIgnoredProperty { get; set; }
}

//在 ConnectionSettings 中设置忽略 FluentMappingPropertyToIgnore 属性
var settings = new ConnectionSettings(new Uri(_esSettings.ServerUri))
.DefaultMappingFor<CompanyWithAttributesAndPropertiesToIgnore>(m => m.Ignore(i => i.FluentMappingPropertyToIgnore))
  • 以上除了 Name 属性外,其他所有属性均会在映射时被忽略掉。

最终结果为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
"ignoremappingtest" : {
"mappings" : {
"properties" : {
"name" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
}
}
}

忽略继承的属性

可以在 ConnectionSettings 使用 Ignore 方法来进行忽略,如上方的 FluentMappingPropertyToIgnore 属性。

假设有以下测试用模型:映射 Child 时忽略 Parent 中的 IgnoreMe 属性

1
2
3
4
5
6
7
8
public class Parent
{
public int Id { get; set; }
public string Description { get; set; }
public string IgnoreMe { get; set; }
}

public class Child : Parent { }

使用 Ignore 属性:

1
2
3
4
5
6
7
8
9
// ConnectionSettings 中设置忽略 IngoreMe
var settings = new ConnectionSettings(new Uri(_esSettings.ServerUri)).DefaultMappingFor<Child>(m => m.IndexName("test").Ignore(i => i.IgnoreMe))

//创建索引:
var createIndexResponse = client.Indices.Create("test", c => c
.Map<Child>(m => m
.AutoMap()
)
);

结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
"mappings": {
"properties": {
"id": {
"type": "integer"
},
"desc": {
"fields": {
"keyword": {
"ignore_above": 256,
"type": "keyword"
}
},
"type": "text"
}
}
}
}

覆盖继承的属性

使用 new 关键字来覆盖基类中的同名属性,以让 ES 在进行数据类型推断时,使用跟父类不同的数据类型。

1
2
3
4
public class ParentWithStringId : Parent
{
public new string Id { get; set; }
}

最终在创建索引的时候,会覆盖 int 类型的 id,如下:

1
2
3
4
5
var createIndexResponse = client.Indices.Create("myindex", c => c
.Map<ParentWithStringId>(m => m
.AutoMap()
)
);

mappging 信息如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"mappings": {
"properties": {
"id": {
"type": "text",
"fields": {
"keyword": {
"ignore_above": 256,
"type": "keyword"
}
}
}
}
}
}
  • 以上结果忽略了 IgnoreMe 和 IgnoreMe 属性。

  • 父类中的 id 是 integer 数据类型。