使用 Elasticsearch 将数组字段映射到 C# 字符串列表
Mapping an array field to a C# string list with Elasticsearch
如图所示,我有一个包含字符串值数组的组字段。
但是,我在尝试将其映射到 List<string>
属性.
时遇到异常
类似于Error converting value \"[134706634,134706635]\" to type System.Collections.Generic.IList[System.String]'
我尝试使用 elasticsearch 提供的一些不同的属性,但 none 有效。 json 转换器属性工作正常,但需要编写大量代码才能使其按我想要的方式工作。
有没有更干净、更原生的方法来使用 NEST 来做到这一点?
C#代码:
var groupQuery = await
elastic.SearchAsync<CorrelationGroup>(s => s
.Query(q => q
.Bool(b => b
.Must(
m => m.ConstantScore(c => c
.Filter(f => f
.Term(x => x.Type, counterType))
),
m => m.ConstantScore(c => c.
Filter(f => f
.Term(x => x.TypeValue, counterTypeValue))))))
.Index("correlation-groups").AllTypes());
public class CorrelationGroup
{
[Text(Name = "type")]
public string Type { get; set; }
[Text(Name = "type_value")]
public string TypeValue { get; set; }
public List<string> Groups { get; set; }
}
源json文件:
[
{
"type": "APN",
"type_value": "internet",
"groups": [150994936,150994940]
},
{
"type": "APN",
"type_value": "internet",
"groups": [150984921,150984922]
},
{
"type": "APN",
"type_value": "internet",
"groups": [150984917,150984918,150984921,150984922]
}
]
我的模板是:
{
"template": "correlation-groups",
"settings" : {
"number_of_shards" : 2,
"number_of_replicas" : 0,
"index" : {
"store" : { "compress" : { "stored" : true, "tv": true } }
}
},
"dynamic_templates": [
{
"string_template" : {
"match" : "*",
"mapping": { "type": "string", "index": "not_analyzed" },
"match_mapping_type" : "string"
}
}
],
"mappings": {
"_default_": {
"properties": {
"type": { "type": "string", "index": "not_analyzed" },
"type_value": { "type": "string", "index": "not_analyzed" },
"groups": { "type": "string"}
}
}
}
}
问题与您的模板有关;在 __default__
映射中,因为您已将 groups
指定为 string
类型,传入的 属性 被 字符串化 并保留在 Elasticsearch 中作为字符串。 Logstash 编解码器将从您的来源 json 正确发送 groups
属性 作为数字数组,但由于您拥有默认映射,将作为字符串持久保存。
要纠正,请将 __default__
映射更改为
"mappings": {
"_default_": {
"properties": {
"type": { "type": "string", "index": "not_analyzed" },
"type_value": { "type": "string", "index": "not_analyzed" },
"groups": { "type": "integer" }
}
}
}
如果索引中只有一种类型,您可能需要显式定义该类型的映射。
完成此操作后,将 C# POCO 更改为
public class CorrelationGroup
{
[Keyword]
public string Type { get; set; }
[Keyword(Name = "type_value")]
public string TypeValue { get; set; }
public List<int> Groups { get; set; }
}
如果您使用 Elasticsearch 5.x,您应该使用映射到旧 not_analyzed
string
类型的 keyword
类型。此外,您只需指定 TypeValue
的名称,因为它使用蛇形外壳(NEST 客户端理解来自 Elasticsearch 的驼峰式命名并将映射到 pascal 大小写 POCO 属性 名称)。最后,我将 Groups
属性 更改为 int
列表。
如图所示,我有一个包含字符串值数组的组字段。
但是,我在尝试将其映射到 List<string>
属性.
类似于Error converting value \"[134706634,134706635]\" to type System.Collections.Generic.IList[System.String]'
我尝试使用 elasticsearch 提供的一些不同的属性,但 none 有效。 json 转换器属性工作正常,但需要编写大量代码才能使其按我想要的方式工作。
有没有更干净、更原生的方法来使用 NEST 来做到这一点?
C#代码:
var groupQuery = await
elastic.SearchAsync<CorrelationGroup>(s => s
.Query(q => q
.Bool(b => b
.Must(
m => m.ConstantScore(c => c
.Filter(f => f
.Term(x => x.Type, counterType))
),
m => m.ConstantScore(c => c.
Filter(f => f
.Term(x => x.TypeValue, counterTypeValue))))))
.Index("correlation-groups").AllTypes());
public class CorrelationGroup
{
[Text(Name = "type")]
public string Type { get; set; }
[Text(Name = "type_value")]
public string TypeValue { get; set; }
public List<string> Groups { get; set; }
}
源json文件:
[
{
"type": "APN",
"type_value": "internet",
"groups": [150994936,150994940]
},
{
"type": "APN",
"type_value": "internet",
"groups": [150984921,150984922]
},
{
"type": "APN",
"type_value": "internet",
"groups": [150984917,150984918,150984921,150984922]
}
]
我的模板是:
{
"template": "correlation-groups",
"settings" : {
"number_of_shards" : 2,
"number_of_replicas" : 0,
"index" : {
"store" : { "compress" : { "stored" : true, "tv": true } }
}
},
"dynamic_templates": [
{
"string_template" : {
"match" : "*",
"mapping": { "type": "string", "index": "not_analyzed" },
"match_mapping_type" : "string"
}
}
],
"mappings": {
"_default_": {
"properties": {
"type": { "type": "string", "index": "not_analyzed" },
"type_value": { "type": "string", "index": "not_analyzed" },
"groups": { "type": "string"}
}
}
}
}
问题与您的模板有关;在 __default__
映射中,因为您已将 groups
指定为 string
类型,传入的 属性 被 字符串化 并保留在 Elasticsearch 中作为字符串。 Logstash 编解码器将从您的来源 json 正确发送 groups
属性 作为数字数组,但由于您拥有默认映射,将作为字符串持久保存。
要纠正,请将 __default__
映射更改为
"mappings": {
"_default_": {
"properties": {
"type": { "type": "string", "index": "not_analyzed" },
"type_value": { "type": "string", "index": "not_analyzed" },
"groups": { "type": "integer" }
}
}
}
如果索引中只有一种类型,您可能需要显式定义该类型的映射。
完成此操作后,将 C# POCO 更改为
public class CorrelationGroup
{
[Keyword]
public string Type { get; set; }
[Keyword(Name = "type_value")]
public string TypeValue { get; set; }
public List<int> Groups { get; set; }
}
如果您使用 Elasticsearch 5.x,您应该使用映射到旧 not_analyzed
string
类型的 keyword
类型。此外,您只需指定 TypeValue
的名称,因为它使用蛇形外壳(NEST 客户端理解来自 Elasticsearch 的驼峰式命名并将映射到 pascal 大小写 POCO 属性 名称)。最后,我将 Groups
属性 更改为 int
列表。