ElasticSearch Ingest Pipeline:创建和更新时间戳字段

2024-01-05

要在我的索引上创建时间戳字段,根据this https://stackoverflow.com/a/66958236/758836回答,我创建了一个摄取管道 https://www.elastic.co/guide/en/elasticsearch/reference/current/ingest.html运行特定索引:

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由摄取管道创建后是否存在?


正如@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/.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ElasticSearch Ingest Pipeline:创建和更新时间戳字段 的相关文章

随机推荐

  • navigator.mediaDevices 在 Chrome 62 的 iOS 上为 null?

    从最新版本的 Chrome 62 开始 仅在 iOS 11 设备下 当我尝试使用navigator mediaDevices 它是空的 文档中没有任何内容表明此功能已被删除 在此期间我开了一个Chrome 下的错误 https bugs c
  • 按特定字母对 JS 字符串数组进行排序

    我必须像这样对字符串数组进行排序 var arr akaw waka kawa akwa 排序类型必须是特定字母 在本例中为 W 因此我的函数必须返回此数组 arr waka kawa akwa akaw 这是一个动态数组 我不知道数组中有
  • 错误:任务“:app:processDebugAndroidTestManifest”执行失败

    这就是我更新 buildToolsVersion 时发生的情况26 0 1 to 26 0 2 错误 任务 all processDebugAndroidTestManifest 执行失败 清单合并失败 属性元数据 android supp
  • Android 应用程序中的所有图像都被视为图标吗?

    这已经困扰我一段时间了 我可能反应过度了 如果是的话请告诉我 但是 我觉得向 Android Studio 项目添加图像资源比应有的困难 不一定说这很难做到 但我觉得这应该是最容易做的事情之一 我对 AS 有点陌生 所以我在这里可能有点不合
  • 如何检测iPhone上的左/右滑动?

    有没有简单的方法来检测 iPhone 的此类手势 我可以使用touchesBegan touchesMoved touchesEnded 但我该如何实现这些手势呢 thz u 您将使用 UISwipeGestureRecognizer 对象
  • 绕着正方形滚动一个圆

    近一个月后 我仍然停留在这个问题上 我设法决定圆圈 或我所说的行人 是否应该向左 向右或向上 向下移动 但我需要有可能移动行人around一座建筑物 这意味着他们必须转角 基本上无论方向如何 他们只需要转90度 非常感谢 import nu
  • Python 中单下划线“_”变量的用途是什么?

    是什么意思 after for在这段代码中 if tbh bag n 0 for in tbh bag atom set n 1 Python 中有 3 个主要的常规用途 保存交互式中最后执行的表达式的结果 口译会议 参见docs http
  • 防止 iOS safari 移动网页窗口,以便发生拖动事件

    我使用 Pep js 进行多点触控上的动态拖动 但我的拖动事件没有被注册 因为当我尝试在 Safari 中拖动对象时 在 iOS 窗口中 窗口本身会移动并跟随我的拖动 如何防止浏览器窗口跟随我的拖动 以便 div 在我的网页中可以拖动吗 这
  • SPRING REST:请求被拒绝,因为未找到多部分边界

    我为 Spring 3 Rest 多部分文件上传做了一个 POC 它工作正常 但是当我尝试与我的应用程序集成时 我遇到了问题 它抛出以下异常 org springframework web multipart MultipartExcept
  • 是否可以创建没有锁的线程安全集合?

    这纯粹是出于兴趣问题 欢迎任何类型的问题 那么是否可以创建没有任何锁的线程安全集合呢 我所说的锁是指任何线程同步机制 包括互斥锁 信号量 甚至互锁 所有这些 是否可以在用户级别而不调用系统函数 好吧 可能实施效果不佳 我对理论上的可能性感兴
  • 如何更改可序列化 python 对象的 json 编码行为?

    更改不可 JSON 序列化的对象的格式很容易 例如 datetime datetime 出于调试目的 我的要求是改变一些自定义对象从基本对象扩展的方式 例如dict and list 以json格式序列化 代码 import datetim
  • PHP-REGEX - 多项选择类型

    我有一个像这样的字符串 str 1 What is love a Haddaway b Haxxaway c Hassaway d Hannaway 2 What is love a Haddaway b Haxxaway c Hassaw
  • 用户名密码验证器和证书

    我有一个使用 net tcp 绑定和自定义 UserNamePasswordValidator 的 Web 服务 用户名和密码由客户端在 Credentials UserName UserName 和 Credentials UserNam
  • 这个 DB2 游标是循环吗?

    无论是命运还是运气 我正在致力于将 DB2 存储过程转换为 SQL Server 存储过程 One thing I could not completely understand in DB2 is cursors1 By looking
  • Java-如何在不扩展比较器的情况下对包含句点/点的字符串数组进行排序?

    这里是Java菜鸟 我想对包含句点 点的字符串数组进行从小到大的排序 所以一个数组包含 1 0 3 1 0 12 1 0 2 排序错误如下 1 0 12 1 0 2 1 0 3 排序时正确地应该 1 0 2 1 0 3 1 0 12 这是我
  • 如何识别 C++ 中的 RTL 字符串

    我需要在打印之前知道文本的方向 我正在使用 Unicode 字符 我怎样才能在 C 中做到这一点 如果你不想使用ICU 你可以随时手动解析统一码数据库 http www unicode org Public UNIDATA UnicodeD
  • 为什么Log4j认为我的项目运行在Servlet环境中

    我有一个简单的java项目 maven 它构建了一个 jar 我们在它上面执行 main 方法 但当我跑步时mvn clean test在项目中我从 log4j 得到一条日志行说 INFO Log4j appears to be runni
  • 如何向 UINavigationBar 添加按钮?

    如何以编程方式向 UINavigationBar 添加按钮 设置的示例代码rightbutton on a NavigationBar UIBarButtonItem rightButton UIBarButtonItem alloc in
  • STM32 暂停调试器时冻结外设

    当到达断点或用户暂停代码执行时 调试器可以停止 Cortex 中代码的执行 但是 当皮质停止在暂停状态下执行代码时 调试器是否会冻结其他外设 例如 DMA UART 和定时器 您只能保留时间 r 取决于外围设备 我在进入主函数时调用以下代码
  • ElasticSearch Ingest Pipeline:创建和更新时间戳字段

    要在我的索引上创建时间戳字段 根据this https stackoverflow com a 66958236 758836回答 我创建了一个摄取管道 https www elastic co guide en elasticsearch