2015-04-06 8 views
6

Ich habe ein elasticsearch Dokument im folgenden Format. Ich muss das "x" Feld teilweise aktualisieren und ein python dict darin hinzufügen.elasticsearch Teilupdate mit Python

{ 
     "_index": "gdata34", 
     "_type": "gdat", 
     "_id": "328091-72341-118", 
     "_version": 1, 
     "_score": 1, 
     "_source": { 
      "d": { 
       "Thursday": { 
        "s": "" 
       }, 
       "Email": { 
        "s": "" 
       }, 
       "Country": { 
        "s": "US" 
       }, 

      }, 
      "x": { 
       "Geo": { 
        "s": "45.335428,-118.057133", 
        "g": [ 
         -118.057133 
         , 
         45.335428 
        ] 
       } 
      }, 
      } 
     } 

Ich habe versucht, den folgenden Code zu aktualisieren:

from elasticsearch import Elasticsearch, exceptions 
import pprint 


elasticsearch = Elasticsearch() 
doc = elasticsearch.get(index='gdata34', doc_type='gdat', id='328091-72341-7') 

elasticsearch.update(index='gdata34', doc_type='gdat', id='328091-72341-7', 
        body={"script":"ctx._source.x += y", 
          "params":{"y":"z"} 
        } 
        ) 
elasticsearch.indices.refresh(index='gdata34') 
new_doc = elasticsearch.get(index='gdata34', doc_type='gdat', id='328091-72341-7') 

ich diese Störung erhalte:

elasticsearch.exceptions.RequestError: TransportError(400, u'ElasticsearchIllegalArgumentException[failed to execute script]; nested: ScriptException[dynamic scripting for [groovy] disabled]; ') 

Was ist der richtige Weg, teilweise Aktualisierung in Elasticsearch mit Python zu tun?

+0

Welche Version von ES verwenden Sie? –

+0

@LukasGraf 1.4.4 – Anish

Antwort

9

Für zukünftige Referenz funktionierte die folgende Methode der partiellen Aktualisierung.

elasticsearch.update(index='gdata34', doc_type='gdat', id='328091-72341-7', 
        body={ 
         'doc': {'x': {'y':'z'}} 
        } 
        ) 
1

Vom ElasticSearch docs on scripting:

We recommend running Elasticsearch behind an application or proxy, which protects Elasticsearch from the outside world. If users are allowed to run dynamic scripts (even in a search request), then they have the same access to your box as the user that Elasticsearch is running as. For this reason dynamic scripting is allowed only for sandboxed languages by default.

Jetzt, in der letzten ES-Version hat es in der Groovy Scripting-Engine ein Fehler in der Verwundbarkeit gewesen, die Scripts ermöglicht die Sandbox zu entkommen und Shell-Befehle wie die execute Benutzer, der die Elasticsearch Java VM ausführt - deshalb wird Groovy sandbox is disabled by default in recent versions und damit die Ausführung von Groovy-Skripts im Anforderungshauptteil oder vom .scripts-Index übergeben. Die einzige Möglichkeit, Groovy-Skripte mit dieser Standardkonfiguration auszuführen, besteht darin, sie im Verzeichnis config/scripts/ auf dem Knoten zu platzieren.

So haben Sie zwei Möglichkeiten:

  • Wenn Ihr ES Instanz nicht direkt zugänglich ist und hinter einem Proxy gesichert, können Groovy Sandbox wieder, indem script.groovy.sandbox.enabled: true in config/elasticsearch.yml auf Ihrem Knoten drehen können (s). Wenn Sie auf Ihre ES-Instanz zugreifen können:
  • Sie können Ihr Skript vorbereiten und auf dem Dateisystem im Verzeichnis config/scripts Ihres Knotens ablegen und es namentlich aufrufen. Details siehe Running Groovy Scripts without Dynamic Scripting.
+0

können wir das folgende verwenden? Elasticsearch.update (index = 'gdata34', doc_type = 'gdat', id = '328091-72341-7', body = { 'doc': {' x ': {' y ':' z '}} } ) – Anish

+1

Ja, aber lesen Sie die [Dokumentation] (http://www.elastic.co/guide/en/elasticsearch/reference/1.4/) docs-update.html) - wenn Sie nicht "detect_noop" angeben: true, führt dies immer dazu, dass das Dokument aktualisiert wird, auch wenn der Zusammenführungsprozess keine Änderungen festgestellt hat. –

+0

Mindestens mit ElasticSearch 2.3 (die neueste Version zu diesem Zeitpunkt) ist 'detect_noop' ​​standardmäßig aktiviert. –

Verwandte Themen