如何在Elasticsearch脚本params中动态匹配文档id获取foundDate?
问题描述
在Elasticsearch中,需要通过脚本计算文档lastFixed(epoch毫秒值)与传入参数中对应id的foundDate(同样是epoch毫秒值)的时间差平均值。
文档结构如下:
{ "id": 11406, // 类型:Long "lastFixed": 1666015888000 // epoch毫秒时间 }
传入的params是<String, Long>映射,键对应文档id,值为对应的foundDate。最初使用expression脚本编写的逻辑如下:
"script": { "source": "(doc['lastFixed'] - params[doc['id']] )/ (1000*60*60)", "lang": "expression", "params": { "11406": 1614084531000, "11473": 1073523856000, "11549": 1447461154000, "43904": 1666015887000, "43905": 1666015887000, "43906": 1666015887000, "43907": 1666015887000, "43908": 1666015888000, "43909": 1666015888000, "43910": 1666015888000 } }
使用嵌套路径聚合处理嵌套的id和lastFixed数组时,尝试动态通过文档id从params取对应值出现解析错误,调整写法后仍无法解决。
解决方案
核心问题有两个:expression语言对动态键的支持有限,以及文档id是Long类型,但params的键是字符串,需要类型转换。改用Painless脚本可以完美解决这个问题,具体调整如下:
- 将脚本语言从
expression改为painless - 将文档中的Long类型id转为字符串,再作为键获取params中的值
- 可选:添加空值判断,避免因id不在params中导致报错
调整后的完整脚本示例:
"script": { "source": """ def foundDate = params[doc['id'].value.toString()]; if (foundDate == null) { return 0; // 或根据需求返回默认值 } return (doc['lastFixed'].value - foundDate) / (1000 * 60 * 60); """, "lang": "painless", "params": { "11406": 1614084531000, "11473": 1073523856000, "11549": 1447461154000, "43904": 1666015887000, "43905": 1666015887000, "43906": 1666015887000, "43907": 1666015887000, "43908": 1666015888000, "43909": 1666015888000, "43910": 1666015888000 } }
如果是嵌套字段场景(使用nest-path-aggr-name),需要修改文档字段的引用路径,比如嵌套字段路径为nested_field,则将doc['id'].value改为doc['nested_field.id'].value即可。
内容的提问来源于stack exchange,提问作者Rushikesh Sabde
相关产品推荐
相关产品推荐

