2017-06-06 68 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(); 

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

相關問題