2013-08-03 13 views
23

Ich versuche, ein Skript zu schreiben, das einen neuen Benutzerdatensatz in ElasticSearch hochlädt, alle Informationen aktualisiert, wenn der Benutzer bereits vorhanden ist, und ein neues PaymentInfo-Objekt an den Payments-Array des Benutzers anfügt, wenn es vorhanden ist im Aktualisierungsobjekt. Hier ist eine vereinfachte Version von dem, was ich arbeite mit so weit:Elasticsearch upsert und an Array anfügen

curl -XPOST 'http://localhost:9200/usrtest/usr/1/_update' -d ' 
{ 
    "doc_as_upsert": true, 
    "doc": { 
     "customerId": "1", 
     "firstName": "Mark", 
     "lastName": "Z", 
     "emailAddress": "[email protected]", 
     "paymentInfo": { 
      "pid": "1", 
      "amt": "10" 
     } 
    } 
}' 

Dieser fast tut, was ich in möchten, dass es das Dokument richtig einfügt oder aktualisiert die doc, wenn ein Benutzer mit der gleichen ID existiert, aber es ist fehlt der Aspekt zum Hinzufügen dieser Zahlungsinfo zum Array paymentInfos des Benutzers, wenn der Benutzer bereits vorhanden ist. Wie es gerade ist, überschreibt es gerade das Objekt paymentInfo. Ich habe versucht, indem dieses Skript zum Update JSON:

"script": "if (ctx._source.containsKey(\"paymentInfos\")) {ctx._source.paymentInfos += paymentInfo;} else {ctx._source.paymentInfos = paymentInfo}" 

aber Elasticsearch ignoriert doc Elemente, wenn das script Element angegeben wird.

Ich fühle mich wie ich hier etwas dummes verpasse, aber ich bin mir nicht sicher. Kann mir hier jemand helfen?

Edit: ich folgendes auch versucht haben:

curl -XPOST 'http://localhost:9200/usrtest/usr/1/_update' -d ' 
{  
    "script": "if (ctx._source.containsKey(\"paymentInfos\")) {ctx._source.paymentInfos += paymentInfo;} else {ctx._source.paymentInfos = paymentInfo}", 
    "upsert": { 
     "customerId": "1", 
     "firstName": "Mark", 
     "lastName": "Z", 
     "emailAddress": "[email protected]", 
     "paymentInfo": { 
      "pid": "1", 
      "amt": "10" 
     } 
    }, 
    "params": { 
     "paymentInfo": { 
      "pid": "1", 
       "amt": "10" 
     } 
    } 
}' 

Welche auch fast tut, was ich es will, dass es die Objekte Payment anhängt, wenn ich das Skript ausführen mehrere Mal, aber ansonsten aktualisiert es das Dokument nicht selbst (dh wenn ich das Skript erneut ausführe, ändere Mark in Mindy, es wird nicht aktualisiert, da upsert Elemente nur verwendet werden, wenn das Dokument nicht bereits existiert).

+0

https://discuss.elastic.co/t/append-to-existing-field/16423 –

+0

Konnten Sie das gesamte Dokument mit einer Bedingung aktualisieren? zB ein Skript und ein Dokument zusammen verwenden? Ich bekomme einen Fehler, dass Skript und Dokument nicht zusammen verwendet werden können. – animageofmine

Antwort

24

Sie einige Array-Klammern zum Einfügen Teil des Skripts hinzufügen möchten.

"script": "if (ctx._source.containsKey(\"paymentInfos\")) {ctx._source.paymentInfos += paymentInfo;} else {ctx._source.paymentInfos = [paymentInfo]}" 

die Unterkunft paymentInfos 'im ersten Abschnitt als ein Objekt definiert, so dass auch nach unten fallen Ihnen verursachen kann.

+2

ist diese Antwort gültig? Wenn ja @Sieben Helix, bitte stimme es ab. – JohnnyM

+1

das hat gut für mich funktioniert – Leabdalla

+0

Wie würde man das gleiche mit Groovy machen? – cwarny