- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
根据 this 在我的索引上创建时间戳字段回答,我创建了一个Ingest Pipeline运行特定索引:
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; }
// always update updated_at
ctx['updated_at'] = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
"""
}
}
]
}
然后我将所有索引设置应用为默认管道
PUT _all/_settings
{
"index": {
"default_pipeline": "auto_now_add"
}
}
之后,我开始将我的对象索引到这些索引中。当我查询一个索引项时,我会得到那个在索引时更新了 updated_at
字段的项,例如:
{
_index: 'my_index_1',
_type: '_doc',
_id: 'r1285044056',
_version: 11,
_seq_no: 373,
_primary_term: 2,
found: true,
_source: {
updated_at: '2021-07-07 04:35:39',
...
}
}
我现在想要一个 created_at
字段,它只在第一次更新,所以我尝试以这种方式更新上面的脚本:
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; }
// always update updated_at
ctx['updated_at'] = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
// don't overwrite if present
if (ctx != null && ctx['created_at'] != null) { return; }
ctx['created_at'] = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
"""
}
}
]
}
但这个解决方案似乎不起作用:条件
if (ctx != null && ctx['created_at'] != null) { return; }
将始终失败,从而导致在索引上的每个对象更新时更新 created_at
,与 updated_at
字段的方式相同,使其无用。那么,如何防止这种情况发生,并确保该字段 created_at
在 Ingestion Pipeline 创建后存在?
最佳答案
如@Val 在 this answer 中所述:
... the ingest pipeline processor(s) will only operate within the context of the document you're sending, not the one stored (if any).
因此,您将无权访问底层 _source
或 doc
,因为摄取管道是为摄取而设计的 阶段,而不是更新 阶段。
当然,您可以保留 auto_now_add
管道以自动添加 updated_at
,并且可以使用 created_at
扩展它(如果尚未存在)在摄取负载中)通过检查 ctx.containsKey
— 因为 ctx
本质上是一个 java Map
:
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;
}
"""
}
}
]
}
但是,这仅在您第一次摄取文档时有效!
运行:
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
,而不是 _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"
}
}
}
这将在不触及 created_at
的情况下增加 updated_at
并添加任何其他参数:
{
"some":"param",
"updated_at":"2021-07-08 10:49:44", <--
"created_at":"2021-07-08 10:39:55",
"your":"new params" <--
}
无耻外挂:我讨论pipelines & scripts在我的 Elasticsearch Handbook 中有详细介绍.
关于ElasticSearch 摄取管道 : create and update timestamp field,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68286853/
标题基本上说明了一切。 我主要对更新案例感兴趣。假设我们正在尝试更新具有时间戳记字段的记录,并且我们希望将该字段设置为记录更新的时间戳记。有没有办法做到这一点? 最佳答案 经过一些实验,我找到了合适的
我正在学习一门类(class),其中我必须将日期转换为 unix 时间戳。 import pandas as pd df = pd.read_csv('file.csv') print type(df
我在两个不同的数据库中运行了相同的语句:我的本地数据库和 Oracle Live SQL . CREATE TABLE test( timestamp TIMESTAMP DEFAULT SY
我在两个不同的数据库中运行了相同的语句:我的本地数据库和 Oracle Live SQL . CREATE TABLE test( timestamp TIMESTAMP DEFAULT SY
bson.timestamp.Timestamp需要两个参数:time 和 inc。 time 显然是存储在 Timestamp 中的时间值。 什么是公司?它被描述为递增计数器,但它有什么用途呢?它应
2016-08-18 04:52:14 是我从数据库中获取的时间戳,用于跟踪我想从哪里加载更多记录,这些记录小于该时间 这是代码 foreach($explode as $stat){
我想将 erlang:timestamp() 的结果转换为正常的日期类型,公历类型。 普通日期类型表示“日-月-年,时:分:秒”。 ExampleTime = erlang:timeStamp(),
我想将 erlang:timestamp() 的结果转换为正常的日期类型,公历类型。 普通日期类型表示“日-月-年,时:分:秒”。 ExampleTime = erlang:timeStamp(),
我是 Java 新手。我正在使用两个 Timestamp 对象 dateFrom和dateTo 。我想检查是否dateFrom比 dateTo早 45 天。我用这个代码片段来比较这个 if(dateF
在将 panda 对象转换为时间戳时,我遇到了这个奇怪的问题。 Train['date'] 值类似于 01/05/2014,我正在尝试将其转换为 linuxtimestamp。 我的代码: Train
我正在努力让我的代码运行。时间戳似乎有问题。您对我如何更改代码有什么建议吗?我看到之前有人问过这个问题,但没能成功。 这是我在运行代码时遇到的错误:'Timestamp' object has no
我正在尝试运行以下查询: SELECT startDate FROM tests WHERE startDate BETWEEN TIMESTAMP '1555248497'
我正在使用 Athena 查询以 bigInt 格式存储的日期。我想将其转换为友好的时间戳。 我试过了: from_unixtime(timestamp DIV 1000) AS readab
最近进行了一些数据库更改,并且 hibernate 映射出现了一些困惑。 hibernate 映射: ...other fields 成员模型对象: public class Mem
rng = pd.date_range('2016-02-07', periods=7, freq='D') print(rng[0].day) print(rng[0].month) 7 2 我想要
rng = pd.date_range('2016-02-07', periods=7, freq='D') print(rng[0].day) print(rng[0].month) 7 2 我想要
我必须在我的数据库中保存 ServerValue.TIMESTAMP 但它必须是一个字符串。当我键入 String.valueOf(ServerValue.TIMESTAMP); 或 ServerVa
在我的程序中,每个表都有一列 last_modified: last_modified int8 DEFAULT (date_part('epoch'::text, now()::timestamp)
我想将此时间戳对象转换为日期时间此对象是在数据帧上使用 asfreq 后获得的这是最后一个索引 Timestamp('2018-12-01 00:00:00', freq='MS') 想要的输出 2
我有一个包含时间序列传感器数据的大表。大型是指分布在被监控的各个 channel 中的从几千到 10M 的记录。对于某种传感器类型,我需要计算当前读数和上一个读数之间的时间间隔,即找到当前读数之前的最
我是一名优秀的程序员,十分优秀!