使用Elasticsearch将数组字段映射到C#字符串列表

时间:2016-08-10 14:20:42

标签: c# elasticsearch nest

如图所示,我有一个包含字符串值数组的groups字段。 但是,我在尝试将其映射到List<string>属性时遇到异常。

Error converting value \"[134706634,134706635]\" to type System.Collections.Generic.IList[System.String]'

这样的东西

我尝试使用elasticsearch提供但不起作用的各种属性。 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"}
            }
         }
     }
 }

LOGSTASH CONF

INDEX

1 个答案:

答案 0 :(得分:2)

问题与您的模板有关;在__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,则应使用映射到旧keyword not_analyzed类型的string类型。此外,您只需要指定TypeValue的名称,因为它使用了蛇形套管(NEST客户端了解来自Elasticsearch的驼峰案例命名,并将映射到pascal案例POCO属性名称)。最后,我已将Groups属性更改为int列表。