2017-06-06 70 views
0

有没有办法使用ElasticSearch script_fields的输出来更新索引中的另一个变量?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" 
        } 
       } 
      } 
      } 
    } 
+0

在脚本字段脚本中使用UpdateRequestBuilder,你不能用'_fields._timestamp'因为访问'_timestamp'它不会被存储,而是使用'doc._timestamp.value'代替。 – Val

+0

但是,脚本更新将不允许您使用'doc._timestamp.value'。 – Val

回答

1

你需要做这个两分:

  1. 运行查询,并得到一个映射ID < - >时间戳和
  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

#!/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 

shell脚本终于可以像这样运行:脚本已经完成运行

./read.sh < twitter.json 

后,您的文档将与_timestamp价值tcopy场。

+0

一旦我的[PR获得合并](https://github.com/logstash-plugins/logstash-input-elasticsearch/pull/74),使用简单的Logstash管道就可以轻松完成所有这些工作。 – Val

+0

太棒了,非常感谢你!真的很感谢这一点。我确实找到了另一种方式来做到这一点,我也发布了。 – user2689782

+0

很酷,很高兴帮助:-) – Val

0

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

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

然后我可以使用此值更新索引

相关问题