web-dev-qa-db-fra.com

Elasticsearch upserting et ajout à la matrice

J'essaie d'écrire un script qui insérera un nouvel enregistrement d'utilisateur dans ElasticSearch, mettant à jour toutes les informations si l'utilisateur existe déjà et ajoutant un nouvel objet PaymentInfo au tableau Payments de l'utilisateur s'il existe dans l'objet de mise à jour. Voici une version simplifiée de ce avec quoi je travaille jusqu'à présent:

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

Cela fait presque ce que je veux en ce sens qu'il insère le document correctement ou met à jour le document si un utilisateur existe avec le même ID, mais il manque l'aspect pour ajouter cette information de paiement au tableau paymentInfos de l'utilisateur si l'utilisateur existe déjà. Comme c'est le cas actuellement, il remplace simplement l'objet paymentInfo. J'ai essayé d'ajouter ce script à la mise à jour JSON:

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

mais elasticsearch ignore les éléments doc lorsque l'élément script est spécifié.

J'ai l'impression de manquer quelque chose de stupide ici, mais je ne suis pas sûr. Est-ce que quelqu'un ici peut m'aider?

Edit: J'ai également essayé ce qui suit:

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

Qui aussi fait presque ce que je veux, en ce qu'il ajoute les objets paymentInfo lorsque j'exécute le script plusieurs fois, mais sinon il ne se met pas à jour le document lui-même (c'est-à-dire que si je relance le script, en changeant Mark en Mindy, il ne se met pas à jour car les éléments upsert ne sont utilisés que si le document n'existe pas déjà).

27
Seventh Helix

vous voudrez ajouter quelques crochets de tableau à la partie d'insertion du script.

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

la propriété 'paymentInfos' dans la première section est définie comme un objet, ce qui peut également vous faire tomber.

27
Paul Blakey