我想更新一个对象的字段,以防它仍然不存在而被创建。
尤其是,我必须在进程开始时注册它的开始时间,并在它结束时注册它的结束时间。在这两种情况下,“ start_time”和“ end_time”都不存在。所以我必须设计两个更新脚本:
该过程开始:创建“过程”对象,创建“ start_date”字段并将其设置为当前DateTime。
该过程结束:创建并将“ end_date”字段设置为当前的DateTime。
我以这种方式完成了映射:
...
"process": {
"properties": {
"start_time": {
"format": "strict_date_optional_time||epoch_second",
"type": "date"
},
"start_time": {
"format": "strict_date_optional_time||epoch_second",
"type": "date"
}
}
},
...
Elasticsearch中存储的文档在所有其他字段中都很丰富,但在“ process”对象中却不存在,但该对象仍然不存在。
我编写了以下脚本(PHP SDK)来设置流程对象启动时的开始时间:
return static::elastic()->update([
'index' => static::$index,
'type' => static::$type,
'id' => $uuid,
'fields' => '_source',
'retry_on_conflict' => 50000,
'body' => [
'script' => [
'source' => 'ctx._source.process.start_time = params.process_start_time',
'lang' => 'painless',
'params' => [
'process_start_time' => strtotime('now')
]
],
'scripted_upsert' => true,
]
]);
,它用于设置进程结束时的结束时间:
return static::elastic()->update([
'index' => static::$index,
'type' => static::$type,
'id' => $uuid,
'fields' => '_source',
'retry_on_conflict' => 50000,
'body' => [
'script' => [
'source' => 'ctx._source.process.end_time = params.process_start_time',
'lang' => 'painless',
'params' => [
'process_end_time' => strtotime('now')
]
],
'scripted_upsert' => true,
]
]);
我希望在该流程开始之前有这份文件(实际上我有):
{
...(other fields)...
}
在该过程开始后,我希望有这个文件:
{
...(other fields)...
'process': {
'start_time': 1566406334
}
}
但是当我运行脚本以更新开始时间时,出现此错误:
{
"error": {
"root_cause": [
{
"type": "remote_transport_exception",
"reason": "[instance-0000000019][10.45.0.57:19703][indices:data/write/update[s]]"
}
],
"type": "illegal_argument_exception",
"reason": "failed to execute script",
"caused_by": {
"type": "script_exception",
"reason": "runtime error",
"script_stack": [
"ctx._source.process.start_time = params.process_start_time",
"^---- HERE"
],
"script": "ctx._source.process.start_time = params.process_start_time",
"lang":"painless",
"caused_by" : {
"type":"null_pointer_exception",
"reason": null
}
}
},
"status":400
}
我认为脚本的结构是正确的,因为如果运行此脚本:
return static::elastic()->update([
'index' => static::$index,
'type' => static::$type,
'id' => $uuid,
'fields' => '_source',
'retry_on_conflict' => 50000,
'body' => [
'script' => [
'source' => 'ctx._source.process_test_value = params.test_value',
'lang' => 'painless',
'params' => [
'test_value' => strtotime('now')
]
],
'scripted_upsert' => true,
]
]);
我获得了预期的结果(即使未映射process_test_value):
{
...(other fields)...
'process_test_value': 1566406334
}
我的错误在哪里? 提前谢谢。