You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Elasticsearch输出插件的脚本函数中访问@metadata字段

解决Logstash Elasticsearch输出脚本中访问@metadata字段的问题

看起来你踩了两个常见的坑:一是默认情况下@metadata字段不会被传入Elasticsearch的脚本参数,二是直接用Logstash变量插值会触发ES的脚本编译限制。我来帮你搞定这个问题:

问题根源

  1. @metadata字段默认不传入脚本:Logstash的Elasticsearch输出插件在传递事件到ES脚本时,不会自动把@metadata里的字段包含到params.event中,所以你用params.event.get("[@metadata][url]")只能拿到null。
  2. 变量插值触发编译错误:如果直接在脚本里用%{[@metadata][url]},Logstash会为每个不同的URL生成新的脚本内容,ES会因为频繁编译新脚本触发too many dynamic script compilations错误。

正确解决方案:用script_params传递元数据字段

你需要通过script_params配置项,把需要的@metadata字段显式传递给ES脚本,这样脚本内容固定,参数动态变化,既不会有编译问题,又能正确拿到字段值。

修改后的完整配置如下:

output {
  elasticsearch {
    hosts => "***************"
    user => "****"
    index => "****"
    password => "*********"
    document_type => "document"
    document_id => "%{[@metadata][domain]}"
    action => "update"
    # 显式传递@metadata中的url到脚本参数
    script_params => {
      "target_url" => "%{[@metadata][url]}"
    }
    # 优化后的脚本,直接引用params.target_url
    script => '
      if (ctx._source.urls.length < 1001) {
        if (!ctx._source.urls.contains(params.target_url)) {
          ctx._source.urls.add(params.target_url);
        }
      }
    '
    doc_as_upsert => true
  }
}

关键改动说明

  1. 添加script_params:把@metadata里的url字段赋值给脚本参数target_url,这样ES脚本就能直接通过params.target_url访问到这个值。
  2. 优化脚本逻辑:用ES的contains方法替代手动循环判断URL是否存在,代码更简洁高效。
  3. 避免动态脚本编译:脚本内容完全固定,只有params.target_url是动态变化的,ES只会编译一次脚本,不会触发编译限制。

另外,记得确保你的ES索引中urls字段是数组类型,否则contains和add操作会报错哦。

内容的提问来源于stack exchange,提问作者24x7

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:31:46