如果endDate值不存在,如何计算弹性搜索中startDate和endDate之间的月数



我现在面临的问题是计算"startDate""endDate";。如果用户具有这两个值,我计算它没有任何问题,但当他/她仍然被使用时(我从isEmployed属性中得到,它是布尔值(;endDate";值为null,这是可以的,但当我试图覆盖该值时,我在字段runtime_mapping中得到了一个强制转换错误。

index mapping:

PUT {{elasticUrl}}/user-experiences
{
"mappings": {
"properties": {
"userId": {
"type": "integer"
},
"experienceId": {
"type": "integer"
},
"startDate": {
"type": "date"
},
"endDate": {
"type": "date"
}
}
}
}

aggregation:

POST {{elasticUrl}}/user-experiences/_search
{
"runtime_mappings": {
"endDate": {
"type": "date",
"script": {
"source": "if (doc['isEmployed'].value == true) { emit(new Date().getTime()) } else { emit (params._source['endDate']) }"
}
}
},
"size": 0,
"aggregations": {
"group_by": {
"terms": {
"field": "userId"
},
"aggregations": {
"start": {
"sum": {
"field": "startDate"
}
},
"end": {
"sum": {
"field": "endDate"
}
},
"duration": {
"bucket_script": {
"buckets_path": {
"start": "start.value",
"end": "end.value"
},
"script": {
"params": {
"month_in_milliseconds": 2628000000
},
"source": "Math.round((params.end - params.start) / params.month_in_milliseconds)"
}
}
},
"duration_bucket_filter": {
"bucket_selector": {
"buckets_path": {
"durationBucket": "duration"
},
"script": {
"params": {
"number_of_months": 1
},
"source": "params.durationBucket >= params.number_of_months"
}
}
}
}
}
}
}

Error message is as followsreason: class java.lang.String cannot be cast to class java.lang.Number (java.lang.String and java.lang.Number are in module java.base of loader 'bootstrap')

{
"error": {
"root_cause": [
{
"type": "script_exception",
"reason": "runtime error",
"script_stack": [
"emit (params._source['endDate']) }",
"                    ^---- HERE"
],
"script": "if (doc['isEmployed'].value == true) { emit(new Date().getTime()) } else { emit (params._source['endDate']) }",
"lang": "painless",
"position": {
"offset": 95,
"start": 75,
"end": 109
}
}
],
"type": "search_phase_execution_exception",
"reason": "all shards failed",
"phase": "query",
"grouped": true,
"failed_shards": [
{
"shard": 0,
"reason": {
"type": "script_exception",
"reason": "runtime error",
"script_stack": [
"emit (params._source['endDate']) }",
"                    ^---- HERE"
],
"script": "if (doc['isEmployed'].value == true) { emit(new Date().getTime()) } else { emit (params._source['endDate']) }",
"lang": "painless",
"position": {
"offset": 95,
"start": 75,
"end": 109
},
"caused_by": {
"type": "class_cast_exception",
"reason": "class java.lang.String cannot be cast to class java.lang.Number (java.lang.String and java.lang.Number are in module java.base of loader 'bootstrap')"
}
}
}
]
},
"status": 400
}

为了解决这个问题,我创建了一个类型为date的updatedEndDate运行时文件,而不是映射中的原始结束日期,我在聚合中使用了运行时字段,解决方案如下所示:

"runtime_mappings": {
"updatedEndDate": {
"type": "date",
"script": {
"source": "if (doc['isEmployed'].value.equals(true)) { emit(new Date().getTime()) } else { emit(doc['endDate'].value.millis) } "
}
}
}

最新更新