Append to a array field


(Jorge Batista) #1

Hello, I am new to ES and but I'm getting the hang of it.
It's a really powerful piece of software, but I have to say that the documentation is really lacking and confusing some times.

Here's my question:
I have an integer array, that looks like this:

"hits_history" : [0,0]

I want to append an integer to that array via an "update_by_query" call, I searched and found this link: https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-update.html
which has this example:

POST test/type1/1/_update
{
    "script" : {
        "inline": "ctx._source.tags.add(params.tag)",
        "lang": "painless",
        "params" : {
            "tag" : "blue"
        }
    }
}

so I tried:

curl -XPOST 'localhost:9200/example/example/_update_by_query?pretty' -H 'Content-Type: application/json' -d'
    {
      "script": {
        "inline": "ctx._source.hits_history.add(params.hits)",
        "params": {"hits": 0}
      },
      "query": {
      	"match_all": {}
    	}
    }
    '

but it gave me this error:

"ctx._source.hits_history.add(params.hits); ",
      "                                   ^---- HERE"
"type" : "script_exception",
    "reason" : "runtime error",
    "caused_by" : {
      "type" : "illegal_argument_exception",
      "reason" : "Unable to find dynamic method [add] with [1] arguments for class [java.lang.Integer]."

So, I looked further and found this: https://www.elastic.co/guide/en/elasticsearch/guide/current/partial-updates.html

which has this example:

We can also use a script to add a new tag to the tags array.

POST /website/blog/1/_update
{
   "script" : "ctx._source.tags+=new_tag",
   "params" : {
      "new_tag" : "search"
   }
}

So I tried it:

curl -XPOST 'localhost:9200/example/example/_update_by_query?pretty' -H 'Content-Type: application/json' -d'
{
  "script": {
    "inline": "ctx._source.hits_history += 0;"
  },
  "query": {
  	"match_all": {}
	}
}
'

Result:

"type" : "script_exception",
    "reason" : "runtime error",
    "caused_by" : {
      "type" : "class_cast_exception",
      "reason" : "Cannot apply [+] operation to types [java.util.ArrayList] and [java.lang.Integer]."

So, how can I append items to the arrayList? Is there a more up-to-date documentation I should look into?

What I wanted to do was simply something like this:

ctx._source.hits_history.add(ctx._source.today_hits); ctx._source.today_hits = 0;

Thank you


(Jorge Batista) #2

anyone?


(Jorge Batista) #3

tried:
.addAll([params.hits])
.add(0, params.hits) (since it says on painless API reference that .add arg 0 is the index)

+= [params.hits]

but to no avail.

PLEASE can someone let me know how to make this work? I'm in a tight schedule


(Mark Harwood) #4

Works for me (running on master branch):

DELETE test
POST test/doc
{
  "hits_history": [0,0]
}
POST /test/doc/_update_by_query?pretty
	{
	  "script": {
		"inline": "ctx._source.hits_history.add(params.hits)",
		"params": {"hits": 1}
	  },
	  "query": {
		"match_all": {}
		}
	}
GET test/doc/_search

(Jorge Batista) #5

hey Mark, what's your mapping for the test doc?


(Mark Harwood) #6
{
  "test": {
	"mappings": {
	  "doc": {
		"properties": {
		  "hits_history": {
			"type": "long"
		  }
		}
	  }
	}
  }
}

(Jorge Batista) #7

ok, just tested with "hits" = 1 (like yours) and it is working. Crazy stuff.


(Jorge Batista) #8

found the bug, turns out one of the items had hits_history as an integer instead of an array ( = 0, instead of = [0]), so it was bugging the whole system

thank you for the reply anyway!


(system) #9

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