Elasticsearch script_fields 更新另一个字段?

Elasticsearch script_fields to update another field?

有没有办法使用 ElasticSearch script_fields 的输出来更新索引中的另一个变量?

我在 ElasticSearch 1.x 中有一个索引,它启用了时间戳,但没有存储。 (映射见下文)

这意味着可以访问时间戳以进行搜索,或者使用 script_fields 之类的 -

GET twitter/_search
{
     "script_fields": {
       "script1": {
          "script": "_fields['_timestamp']" 
        }
  }
}

我需要提取这个时间戳字段,并将其存储在索引中。编写脚本来复制任何其他字段很容易,例如(我正在使用更新 API)

ctx._source.t1=ctx._source.message

但是如何使用 script_fields 输出中的值来更新索引中的另一个字段?我希望字段 'tcopy' 获取每个文档的时间戳值。

此外,我尝试使用 java 获取如下值,但它返回 null。

SearchResponse response = client.prepareSearch("twitter")
                .setQuery(QueryBuilders.matchAllQuery())
                .addScriptField("test", "doc['_timestamp'].value")
                .execute().actionGet();

映射

 {
         "mappings": {
             "tweet": {
                "_timestamp": {
                   "enabled": true,
                   "doc_values" : true
                },
                "properties": {
                   "message": {
                      "type": "string"
                   },
                   "user": {
                      "type": "string"
                   },
                   "tcopy": {
                      "type": "long"
                   }
                }
             }
          }
    }

您需要在 运行 秒内完成此操作:

  1. 运行查询并得到一个映射id<->timestamp and
  2. 然后 运行 带有时间戳的批量更新

因此,要从 twitter 索引中提取时间戳数据,您可以像这样使用 elasticdump

elasticdump \
   --input=http://localhost:9200/twitter \
   --output=$ \
   --searchBody '{"script_fields": {"ts": {"script": "doc._timestamp.value"}}}' > twitter.json

这将生成一个名为 twitter.json 的文件,其中包含以下内容:

{"_index":"twitter","_type":"tweet","_id":"1","_score":1,"fields":{"ts":[1496806671021]}}
{"_index":"twitter","_type":"tweet","_id":"2","_score":1,"fields":{"ts":[1496807154630]}}
{"_index":"twitter","_type":"tweet","_id":"3","_score":1,"fields":{"ts":[1496807161591]}}

然后您可以轻松地使用该文件来更新您的文档。首先创建一个名为 read.sh

的 shell 脚本
#!/bin/sh
while read LINE; do 
    INDEX=$(echo "${LINE}" | jq '._index' | sed "s/\"//g"); 
    TYPE=$(echo "${LINE}" | jq '._type' | sed "s/\"//g"); 
    ID=$(echo "${LINE}" | jq '._id' | sed "s/\"//g"); 
    TS=$(echo "${LINE}" | jq '.fields.ts[0]'); 
    curl -XPOST "http://localhost:9200/$INDEX/$TYPE/$ID/_update" -d "{\"doc\":{\"tcopy\":"$TS"}}"
done

最后你可以 运行 像这样:

./read.sh < twitter.json

脚本完成 运行ning 后,您的文档将有一个具有 _timestamp 值的 tcopy 字段。

可以使用 java 访问 _timestamp 字段。然后,我们可以使用 Update API 来设置新字段。请求看起来像

SearchResponse response = client.prepareSearch("twitter2")
                .setQuery(QueryBuilders.matchAllQuery())
                .addScriptField("test", "doc['_timestamp'].value")
                .execute().actionGet();

然后我可以将 UpdateRequestBuilder 与使用此值更新索引的脚本一起使用