date - Elasticsearch中日期数据类型的平均聚合?
问题描述
我使用存储的脚本在我的索引中存储了 3 个日期数据类型变量(date1、date2、date3)。我计算了两个日期变量(date2 - date1)之间的持续时间并存储在第三个日期变量(date3)中。这是我使用过的完整映射、脚本和更新请求。
PUT /myindex
POST /myindex/_mappings
{
"properties":{
"date1":{
"type":"date"
},
"date2":{
"type":"date"
},
"date3":{
"type":"date"
}
}
}
POST _scripts/myindexscript/
{
"script":{
"source" :"""
if (ctx._source.date1==null) {
ctx._source.date1 = new Date().getTime();
}
ctx._source.status.add(params.status);
if (!(params.status).equalsIgnoreCase('Info')) {
ctx._source.date2 = new Date().getTime();
ctx._source.date3=ctx._source.date2 - ctx._source.date1;
}
""",
"lang": "painless"
}
}
POST /myindex/_update/1
{
"script":{
"id":"myindexscript",
"params":{
"status": "Infoa"
}
}
, "upsert": {
"date1":null,
"date2":null,
"date3":null,
"status": []
},
"scripted_upsert": true
}
如您在此处看到的,我已插入 1 个文档。为了在文档中插入,我首先使用字段 status='Info' 然后运行字段 status!='Infoa' 的 _update 请求。在这里你可以看到 GET /myindex/_search 的输出
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "myindex",
"_type" : "_doc",
"_id" : "1",
"_score" : 1.0,
"_source" : {
"date3" : 5589,
"date2" : 1590062272146,
"date1" : 1590062266557,
"status" : [
"Info",
"Infoa"
]
}
}
]
}
}
现在我运行这个特定的聚合请求
GET /myindex/_search
{
"query": {
"term": {
"status.keyword": {
"value": "Infoc"
}
}
},
"aggs": {
"NAME": {
"avg": {
"field": "date3"
}
}
},
"size": 20
}
这给出了这个奇怪的输出:
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 0.8025915,
"hits" : [
{
"_index" : "myindex",
"_type" : "_doc",
"_id" : "1",
"_score" : 0.8025915,
"_source" : {
"date3" : 5589,
"date2" : 1590062272146,
"date1" : 1590062266557,
"status" : [
"Info",
"Infoa"
]
}
}
]
},
"aggregations" : {
"NAME" : {
"value" : 1.142046432E14,
"value_as_string" : "5589-01-01T00:00:00.000Z"
}
}
}
为什么聚合结果中的值不是 5589 而是 "value" : 1.142046432E14 。我无法理解如何处理 date3 字段以进行平均计算。请帮忙?
解决方案
两个毫秒时间戳日期的差是一个整数。在你的情况下
1590062272146 - 1590062266557 = 5589
由于您的映射规定date3
为 type date
,因此 ES 尝试解析它。它猜测它是一年,所以结果日期是Jan 1st, year 5589
,以毫秒为单位确实是1.142046432E14
,即114204643200000
。
所以数学是对的。
现在,
date2
在UTC是Thu May 21 2020 11:57:52
date1
在UTC是Thu May 21 2020 11:57:46
所以两者的差异,四舍五入,是 6 秒。
您现在基本上有两种选择:
- 调用其他类似的
date3
东西milli_diff
并使其成为integer
而不是date
. 那么您的avg
agg 结果也将以毫秒为单位 - 将
date3
默认设置为format
ofepoch_millis
并在其上执行您的日期魔法(例如在此示例scripted_metric
中的聚合中漂亮地打印平均经过的差异)
推荐阅读
- amazon-cognito - AWS-Amplify 在“忘记密码”时全局注销所有用户
- mongodb - MongoDB - 更新字段的数据类型
- python-3.x - 线程在 Django 中被阻塞 - Python
- python - 在 Python 中更改函数的范围
- python - 使用python的双重消费,第二个参数取决于第一个
- javascript - Javascript按最近日期到最旧日期对对象数组进行排序?
- mysql - 用非索引理解 mysql 限制
- javascript - 如何在 javascript 上返回 Set() 的值
- sql - 在 SQL 查询中使用小数
- git - 面对git的“内容相同”问题