2017-06-06 8 views
0

Gibt es eine Möglichkeit, die Ausgabe eines ElasticSearch script_fields zu verwenden, um eine andere Variable im Index zu aktualisieren?Elasticsearch script_fields um ein anderes Feld zu aktualisieren?

Ich habe einen Index in ElasticSearch 1.x, der Timestamp aktiviert hat, aber nicht gespeichert. (Siehe unten für mapping)

Dies bedeutet, dass der Zeitstempel kann für die Suche zugegriffen werden kann, oder mit script_fields wie -

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

Ich brauche dieses Zeitstempel-Feld zu extrahieren, und speichern Sie es im Index. Es ist einfach genug, ein Skript zu schreiben, um irgendein anderes Feld zu kopieren, z. (Ich bin mit dem Update API)

ctx._source.t1=ctx._source.message 

Aber wie kann ich den Wert aus der script_fields Ausgabe ein anderes Feld im Index zu aktualisieren? Ich möchte, dass das Feld 'tcopy' den Wert des Zeitstempels für jedes Dokument erhält.

Weiter habe ich versucht, Java zu verwenden, um die Werte wie folgt zu erhalten, aber es gab null zurück.

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

Die Abbildung

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

In Ihrem Skript Feld zu aktualisieren, können Sie nicht auf den '' _timestamp' mit _fields._timestamp' seit Es wird nicht gespeichert, sondern stattdessen 'doc._timestamp.value'. – Val

+0

Ein Skript aktualisiert erlaubt jedoch nicht die Verwendung von 'doc._timestamp.value'. – Val

Antwort

1

Sie müssen dies in zwei Läufen tun:

  1. Führen Sie die Abfrage und eine Mapping-ID < -> Zeitstempel und
  2. Führen Sie dann ein Massenupdate mit dem Zeitstempel

So die Zeitstempel-Daten von Ihrem twitter Index extrahieren Sie können zum Beispiel elasticdump wie folgt verwenden:

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

Diese eine Datei twitter.json genannt produzieren wird mit folgendem Inhalt:

{"_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]}} 

Sie können diese Datei dann problemlos zum Aktualisieren Ihrer Dokumente verwenden. Zuerst ein Shell-Skript 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 

namens erstellen Und schließlich können Sie es wie folgt ausführen:

./read.sh < twitter.json 

Nachdem das Skript ausgeführt wird beendet, Ihre Dokumente ein tcopy Feld mit dem _timestamp Wert haben wird.

+0

Sobald mein [PR wird zusammengeführt] (https://github.com/logstash-plugins/logstash-input-elasticsearch/pull/74), wird es einfacher sein, all dies mit einer einfachen Logstash-Pipeline zu tun. – Val

+0

Super, vielen Dank! Schätze das wirklich. Ich habe einen anderen Weg gefunden, das auch zu tun. – user2689782

+0

Cool, froh, dass es hilft :-) – Val

0

Das _timestamp-Feld kann mit Java aufgerufen werden. Dann können wir das Update-API verwenden, um das neue Feld festzulegen. Der Antrag würde aussehen wie

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

Dann kann ich mit einem Skript verwenden UpdateRequestBuilder, die diesen Wert verwendet den Index

Verwandte Themen