web-dev-qa-db-ja.com

Elasticsearchのアップサートと配列への追加

新しいユーザーレコードをElasticSearchにアップサートし、ユーザーが既に存在する場合は情報を更新し、新しいPaymentInfoオブジェクトを更新オブジェクトに存在する場合はユーザーのPayments配列に追加するスクリプトを記述しようとしています。これが私がこれまでに取り組んでいることの簡単なバージョンです:

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"
        }
    }
}'

これは、ドキュメントを適切に挿入したり、ユーザーが同じIDでユーザーが存在する場合にドキュメントを更新したりすることでほぼ望みどおりですが、ユーザーが既に存在する場合は、このpaymentInfoをユーザーのpaymentInfos配列に追加するためのアスペクトがありません。現在のところ、paymentInfoオブジェクトをオーバーライドするだけです。このスクリプトを更新JSONに追加してみました。

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

ただし、doc要素が指定されている場合、elasticsearchはscript要素を無視します。

ここで何かばかげたことを見逃しているような気がしますが、よくわかりません。ここの誰かが私を助けてくれますか?

編集:私も以下を試しました:

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"
         }
    }
}'

また、almostは、スクリプトを数回実行したときにpaymentInfoオブジェクトを追加しますが、それ以外の場合は更新しません。ドキュメント自体(つまり、スクリプトを再度実行してMarkをMindyに変更した場合、upsert要素はドキュメントがまだ存在しない場合にのみ使用されるため、更新されません)。

27
Seventh Helix

スクリプトの挿入部分にいくつかの配列ブラケットを追加する必要があります。

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

最初のセクションの「paymentInfos」プロパティはオブジェクトとして定義されているため、転倒する可能性もあります。

27
Paul Blakey