我现在面临的问题是计算"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 follows
: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')
{
"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) } "
}
}
}