c# - 文本或整数的 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
有没有更好的方法来处理这种情况?如果没有,是否有更强大的整数转换脚本方法?
解决方案
... 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
}
}
}
}
}
推荐阅读
- javascript - 如何通过反斜杠拆分数组的字符串?
- c++ - 在 C++ 中,有没有办法根据输入类是否抽象来定义模板行为?
- ruby-on-rails - 将数字插入数组并检查
- laravel - 如何在 Laravel 8 Jetstream 上使用 NPM 安装 CKEditor
- amazon-web-services - 有没有办法配置 terragrunt 为远程状态创建 s3 存储桶
- python - 将 Python 制作的 15000x 凭证代码导出到 Excel
- python - Django从视图中确定模板中复选框的值
- excel - 工具箱中的“未知”控件
- django - Django - 此 UpdateView 如何返回过滤后的 TableView?
- c# - SQL Server FOR XML PATH('')) 加密数据需要在 C# 中解密