Painless script error adding nested items


(Paul McMahon) #1

Hi,

I'm having a bit of an issue getting a script working; basically, the script is intended to add a nested item to an existing doc.

To repro, I created an index with this mapping:

curl -XPUT 'http://localhost:9200/nsttest' 
{
"mappings": 
    { "test": 
        { "properties": 
                { 
                "prntId" : {"type": "keyword",  "doc_values": true },
		"kids" : {
		        "type": "nested", 
		        "properties": { 
			                "ctxt": {"type": "keyword",  "doc_values": true },
			                "tkn": {"type": "keyword",  "doc_values": true }  
			                } 
                                }
                        } 
                }  
        } 
}

And added a single doc:

curl -XPUT 'http://localhost:9200/nsttest/test/abc'
{
  "prntId" : "abc"
}
curl -XPOST 'http://localhost:9200/nsttest/test/abc/_update'
{
	"script": 
	{ 
		"inline" :  "if (ctx._source.kids == null || ctx._source.kids.size() == 0){ ctx._source.kids = params.kid}  else {ctx._source.kids += params.kid } ", 
		"lang": "painless",
		"params": {"kid":  [{"ctxt" : "xs123", "tkn" : "4eef3f46-5469-42d4-91c2-371748d0ee13"}] }
	}
}

curl -XPOST 'http://localhost:9200/nsttest/test/abc/_update/pretty'
{
	"script": 
	{ 
		"inline" :  "if (ctx._source.kids == null || ctx._source.kids.size() == 0){ ctx._source.kids = params.kid}  else {ctx._source.kids += params.kid } ", 
		"lang": "painless",
		"params": {"kid":  [{"ctxt" : "xs1234", "tkn" : "5eef3f46-5469-42d4-91c2-371748d0ee13"}] }
	}
}

I have tried the params with and without the square brackets, and basically many variations, and it will work updating a doc for the first time, but not thereafter - i.e. "ctx._source.kids += params.kid " always fails...

Here is the error I get:

{
  "error" : {
    "root_cause" : [
      {
        "type" : "remote_transport_exception",
        "reason" : "[bpQJEwv][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 apply [+] operation to types [java.util.ArrayList] and [java.util.HashMap]."
      },
      "script_stack" : [
        "ctx._source.kids += params.kid } ",
        "                          ^---- HERE"
      ],
      "script" : "if (ctx._source.kids == null || ctx._source.kids.size() == 0){ ctx._source.kids = params.kid}  else {ctx._source.kids += params.kid } ",
      "lang" : "painless"
    }
  },
  "status" : 400
}

Anyone have any ideas or pointers?

Thanks in advance!

Paul


(Nik Everett) #2

Try ctx._source.kids.add(params.kid). + only works for math in Painless. I don't recall the justification, but it might be around overhead of doing the extra type checking in the dynamic case or the extra complexity. I'm unsure.


(Paul McMahon) #3

Legend :slight_smile: Obvious in retrospect, can't believe I didn't see it!

Thanks a bunch - much appreciated!

P


(Paul McMahon) #4

Here's the script in working form, in case anyone is interested - note the square brackets in the params for the case when ctx._source.kids = params.kid executes, and the ctx._source.kids.add(params.kid[0]) for the other case

{
	"script": 
	{ 
		"inline" :  "if (ctx._source.kids == null || ctx._source.kids.size() == 0){ ctx._source.kids = params.kid}  else {ctx._source.kids.add(params.kid[0]) } ", 
		"lang": "painless",
		"params": {"kid":  [{"ctxt" : "xs123", "tkn" : "4eef3f46-5469-42d4-91c2-371748d0ee13"}] }
	}
}

(Chetan Vartak) #5

Hi,
Do you know how to invoke the same painless from logstash. Basically need help on how to pass parameters to painless in logstash.
There is another question stuck on the same issue - Update Nested object with logstash

Thanks


(system) #6

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.