更新不存在的Elasticsearch映射对象的字段

时间:2019-08-21 18:11:07

标签: php elasticsearch

我想更新一个对象的字段,以防它仍然不存在而被创建。

尤其是,我必须在进程开始时注册它的开始时间,并在它结束时注册它的结束时间。在这两种情况下,“ start_time”和“ end_time”都不存在。所以我必须设计两个更新脚本:

  1. 该过程开始:创建“过程”对象,创建“ start_date”字段并将其设置为当前DateTime。

  2. 该过程结束:创建并将“ 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
}

我的错误在哪里? 提前谢谢。

0 个答案:

没有答案