为什么要使用轻松的脚本将数组添加到数组?

hel*_*bye 6 elasticsearch logstash elasticsearch-painless

使用 Logstash,我的目标是如果该文档的时间戳之前尚未被索引,则对该文档建立索引,否则,如果该文档确实存在并且时间戳不在数组中,则附加时间戳数组。我的问题是一个数组附加到一个数组。

即我的输入日志行始终相同,除了我想要附加到 Elastic 中同一文档的时间戳。

这是我的输入数据。

  • 请注意,时间戳是一个字符串。
  • “hash”字段将成为文档 ID(仅作为示例)

    {"timestamp":"1534023333", "hash":"1"}
    {"timestamp":"1534022222", "hash":"1"}
    {"timestamp":"1534011111", "hash":"1"}
    
    Run Code Online (Sandbox Code Playgroud)

这是我的 Logstash 配置:

  • 时间戳字段被拆分,将其变成一个数组。
  • 第一次看到文档时,它会被索引。下次看到它时,脚本就会运行。
  • 该脚本会检查时间戳值是否存在,如果不存在,则追加。
  • 使用 params.event.get 是因为它阻止动态脚本编译

    input {
      file {
        path => "timestamp.json"
        start_position => "beginning"
        codec => "json"
      }
    }
    
    filter {
        mutate {
            split => { "timestamp" => "," }
        }
    }
    
    output {
      elasticsearch {
        hosts => ["http://127.0.0.1:9200"]
        index => "test1"
        document_id => "%{[hash]}"
        doc_as_upsert => true
        script =>     'if(ctx._source.timestamp.contains(params.event.get("timestamp"))) return true; else (ctx._source.timestamp.add(params.event.get("timestamp")))'
        action => "update"
        retry_on_conflict=>3
    
      }
      #stdout { codec => rubydebug }
    }
    
    Run Code Online (Sandbox Code Playgroud)

这是输出。

我想要的输出是:

 "timestamp": [
      "1534011111",
      "1534022222"
      "1534023333"
    ],
Run Code Online (Sandbox Code Playgroud)

如何获得所需的输出?我正在运行 Elasticsearch 6.4.2 和 Logstash 6.4.2。

ban*_*nuj 2

问题在于将字段split => { "timestamp" => "," }转换timestamp为数组,add方法接受一个对象并将其附加到原始数组(它不会连接两个数组)。

尝试轻松地访问timestamp数组的第一个元素,如下所示: if(ctx._source.timestamp.contains(params.event.get("timestamp")[0])) return true; else (ctx._source.timestamp.add(params.event.get("timestamp")[0]))