10

I'm following an Elasticsearch tutorial, but ran into a problem when trying to use parameters in a script.

Step 1: Create a new document - OK (index = website; type = blog; id = 1)

curl -XPUT localhost:9200/website/blog/1?pretty -d '{
  "title":"my first post",
  "tags" : [ "tag1" ]
}'

Step 2: Use script to append an extra value to tags array - ERROR

curl -XPOST localhost:9200/website/blog/1/_update?pretty -d '{
   "script" : "ctx._source.tags+=new_tag",
   "params" : {
      "new_tag" : "tag2"
   }
}'

The error message is this, mentioning "reason" : "Variable [new_tag] is not defined." But I have defined the variable new_tag as described on the tutorial page. What am I doing wrong?

  "error" : {
    "root_cause" : [
      {
        "type" : "remote_transport_exception",
        "reason" : "[mrukUvA][127.0.0.1:9300][indices:data/write/update[s]]"
      }
    ],
    "type" : "illegal_argument_exception",
    "reason" : "failed to execute script",
    "caused_by" : {
      "type" : "script_exception",
      "reason" : "compile error",
      "caused_by" : {
        "type" : "illegal_argument_exception",
        "reason" : "Variable [new_tag] is not defined."
      },
      "script_stack" : [
        "ctx._source.tags+=new_tag",
        "                  ^---- HERE"
      ],
      "script" : "ctx._source.tags+=new_tag",
      "lang" : "painless"
    }
  },
  "status" : 400
}

Step 2 (retry) Qualifying new_tag with params - ERROR

curl -XPOST localhost:9200/website/blog/1/_update?pretty -d '{
   "script" : {
       "inline": "ctx._source.tags+=params.new_tag",
       "params" : {
          "new_tag" : "tag2"
       }
   }
}'

Gives error

{
  "error" : {
    "root_cause" : [
      {
        "type" : "remote_transport_exception",
        "reason" : "[mrukUvA][127.0.0.1:9300][indices:data/write/update[s]]"
      }
    ],
    "type" : "illegal_argument_exception",
    "reason" : "failed to execute script",
    "caused_by" : {
      "type" : "script_exception",
      "reason" : "runtime error",
      "caused_by" : {
        "type" : "class_cast_exception",
        "reason" : "Cannot cast java.lang.String to java.util.ArrayList"
      },
      "script_stack" : [
        "ctx._source.tags+=params.new_tag",
        "                        ^---- HERE"
      ],
      "script" : "ctx._source.tags+=params.new_tag",
      "lang" : "painless"
    }
  },
  "status" : 400
}

As a sanity check to make sure the document is valid

$ curl -XGET localhost:9200/website/blog/1?pretty
{
  "_index" : "website",
  "_type" : "blog",
  "_id" : "1",
  "_version" : 27,
  "found" : true,
  "_source" : {
    "title" : "my first post",
    "tags" : [
      "tag1"
    ]
  }
}

So the document does have the valid field tag which is an array.

4
  • 1
    You may need to access the variable with params.new_tag. You need to state that it comes from the params. Commented Mar 28, 2017 at 20:23
  • Thanks @christinabo I tried that, but doing so gives a different error caused_by: type: script_exception", reason:"runtime error", "null_pointer_exception" Looks like this arises from trying to dereference params. I'm guessing the tutorial suggests params has special meaning here. Commented Mar 28, 2017 at 20:27
  • Which version of ES are you using? Commented Mar 29, 2017 at 3:58
  • @Val I am using 5.2.2 Commented Mar 29, 2017 at 13:36

2 Answers 2

22

Your syntax is slightly off, if you have parameters you need to inline the script. Try this:

curl -XPOST localhost:9200/website/blog/1/_update?pretty -d '{
   "script" : {
       "inline": "ctx._source.tags.add(params.new_tag)",
       "params" : {
          "new_tag" : "tag2"
       }
   }
}'
Sign up to request clarification or add additional context in comments.

5 Comments

Hi @Val, seems it still gets the same error :-( I updated my question to include this attempt.
My bad, you need to prefix new_tag with params
Interesting, this time I'm getting "Cannot cast java.lang.String to java.util.ArrayList", I guess now the script syntax needs to be fixed somehow!
painless is no groovy (the += operator in groovy needs to be changed to a method call to the add method) :-) See my updated answer
I see! This worked - "result" : "updated" Thank you very much @Val!
5

you can use "inline" although it is deprecated. now you alse can use "source" to replace "inline" for no warnings. for example:

"script" : {
     "source": "ctx._source.tags.add(params.new_tag)",
     "params": {
       "new_tag":"tag1"
     }
   }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.