首页 > 解决方案 > 文本或整数的 ElasticSearch 聚合

问题描述

我们有一个过程,我们的 Web 服务在 ElasticSearch(C#,使用 NEST)中创建日志记录。ES 索引名称包括月份和年份。

聚合程序(C#,不使用 NEST)从各种日志中提取近乎实时的信息。它由日期直方图、一些项(主机、ip 等)和一些整数字段的总和组成。它发出类似这样的请求:

{
    "size":0,
    "query": {
        "range":{"date":{"gt":"2018-10-01T00:00:00","lte":"2018-10-01T01:00:00"}}
    },
    "aggs": {
        "myBuckets": {
            "composite": {
                "size":100,
                "sources": [
                    {"host":{"terms":{"field":"host.keyword","missing":""}}},
                    {"ipAddress":{"terms":{"field":"ipAddress.keyword","missing":""}}},
                    {"date":{"date_histogram":{"field":"date","interval":"1h"}}}
                ]
            },
            "aggregations": {
                "records":{"sum":{"field":"records","missing":0}}
            }
        }
    }
}

问题在于这些整数字段,因为偶尔流氓/错误 Web 服务会使用字符串而不是整数。这会导致 ES 更改字段的索引映射(从整数到字符串),并破坏聚合器。

通过重新索引来修复索引不是一种选择,如果可能的话,我们更愿意即时处理这个问题。

我目前的计划是读取索引的映射并将求和聚合切换为类似于以下的无痛脚本:

doc['badField.keyword'].value!=null ? Integer.parseInt(doc['badField.keyword'].value) : 0

有没有更好的方法来处理这种情况?如果没有,是否有更强大的整数转换脚本方法?

标签: c#elasticsearchnest

解决方案


... ES 改变索引对字段的映射

ES 永远不会改变一个字段的映射,一旦它被创建。发生这种情况的唯一方法是,如果您发送的第一条记录具有字符串值而不是整数值。

您可以通过在索引第一条记录之前使用创建索引模板来轻松克服这个问题:

PUT _template/my-template
{
  "index_patterns": ["my-index*"],
  "mappings": {
    "_doc": {
      "properties": {
        "my_integer_field": {
          "type": "integer"           <---- this will always be honored
          "ignore_malformed": true    <---- ignore if the value really isn't an integer
        }
      }
    }
  }
}

推荐阅读