使用 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 列表。