正如@Val 在中所描述的这个答案 https://stackoverflow.com/a/51435984/8160318:
...摄取管道处理器将仅运行在上下文中 https://www.elastic.co/guide/en/elasticsearch/painless/7.13/painless-ingest-processor-context.html#painless-ingest-processor-context您发送的文档,而不是存储的文档(如果有)。
因此,您将无权访问底层_source
nor doc
因为摄取管道是为ingest阶段,而不是update phase.
您当然可以保留您的auto_now_add
自动添加管道updated_at
,你可以用它来扩展它created_at
(如果尚未存在于摄取有效负载中)通过检查ctx.containsKey
- 自从ctx
本质上是一个javaMap
:
PUT _ingest/pipeline/auto_now_add
{
"description": "Assigns the current date if not yet present and if the index name is whitelisted",
"processors": [
{
"script": {
"source": """
// skip if not whitelisted
if (![ "my_index_1",
"my_index_2",
"..."
].contains(ctx['_index'])) { return; }
def now = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
// guaranteee updated_at
ctx['updated_at'] = now;
// add created_at only if nonexistent in the payload
if (!ctx.containsKey('created_at')) {
ctx['created_at'] = now;
}
"""
}
}
]
}
但是,这仅在您第一次摄取文档时有效!
Running:
POST my_index_1/_doc/some_id
{
"some": "param"
}
将产生:
{
"some" : "param",
"updated_at" : "2021-07-08 10:35:13",
"created_at" : "2021-07-08 10:35:13"
}
现在,为了自动递增updated_at
每次更新文档时,你还需要一个脚本— 这次存储在_scripts
, not _ingest/pipeline
:
PUT _scripts/incement_update_at__plus_new_params
{
"script": {
"lang": "painless",
"source": """
// add whatever is in the params
ctx._source.putAll(params);
// increment updated_at no matter what was in the params
ctx._source['updated_at'] = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
"""
}
}
然后,当你运行你的_update
打电话,通过提到上述内容来做到这一点script
:
POST my_index_1/_doc/some_id/_update
{
"script": {
"id": "incement_update_at__plus_new_params",
"params": {
"your": "new params"
}
}
}
这会增加updated_at
不碰created_at
并添加任何其他参数:
{
"some":"param",
"updated_at":"2021-07-08 10:49:44", <--
"created_at":"2021-07-08 10:39:55",
"your":"new params" <--
}
无耻插件:我讨论管道和脚本 https://elasticsearchbook.com/learn-elasticsearch/post-indexing-updates-488d69498920464999ef35e36e3e8095非常详细地在我的Elasticsearch 手册 https://elasticsearchbook.com/.