Script having issue with long data type


(Sree2k) #1

Hello,

I'm kind of new to elasticsearch. I had a question regarding using transport client ( v5.0.1 and my elasticsearch cluster is also at 5.0.1). I'm seeing this error when I try to call update operation.

My document is of following format:

{
x: [ _array_of_longs]
}

I tried to use script to have an append only if it exists in the array kind of operation. I don't know if elasticsearch supports Set data structure. Whenever i try with small integer like 100, 200 it works. But when I enter longs, l get this error. Any idea, what I'm doing wrong here ?

Caused by: java.lang.IllegalArgumentException: Invalid int constant [9000000000001].
at org.elasticsearch.painless.Executable$Script.compile(if(ctx._source.x.contains(9000000000001)) { ctx.op = 'none'} else { ctx._source.x.add(9000000000001)} @ :33) ~[na:na]
at org.elasticsearch.painless.node.ENumeric.analyze(ENumeric.java:107) ~[na:na]
at org.elasticsearch.painless.node.PSubDefCall.analyze(PSubDefCall.java:67) ~[na:na]
at org.elasticsearch.painless.node.PCallInvoke.analyze(PCallInvoke.java:92) ~[na:na]
at org.elasticsearch.painless.node.SIfElse.analyze(SIfElse.java:66) ~[na:na]
at org.elasticsearch.painless.node.SSource.analyze(SSource.java:190) ~[na:na]
at org.elasticsearch.painless.node.SSource.analyze(SSource.java:162) ~[na:na]
at org.elasticsearch.painless.Compiler.compile(Compiler.java:104) ~[na:na]
at org.elasticsearch.painless.PainlessScriptEngineService$2.run(PainlessScriptEngineService.java:171) ~[na:na]
at org.elasticsearch.painless.PainlessScriptEngineService$2.run(PainlessScriptEngineService.java:168) ~[na:na]
at java.security.AccessController.doPrivileged(Native Method) ~[na:1.8.0_31]
at org.elasticsearch.painless.PainlessScriptEngineService.compile(PainlessScriptEngineService.java:168) ~[na:na]


I'm using prepareUpdate call from transport client (lang is painless) something like this ...
client.prepareUpdate(request.getIndex(),
request.getType(), request.getId())
.setScript(request.getScript()).setUpsert(request.getDocument()).execute().get();


The Best Practice to Updates Lot of Documents
(Sree2k) #2

Have anyone seen this issue before ?

Mapping query shows that type has long defined.


(Xavier Facq) #3

I'm using version 2.4.2 and I have same kind of updates. I have to use a script forcing long : here is my script (lang is groovy)

    /*
     * Elasticsearch Groovy script (Ref https://www.elastic.co/guide/en/elasticsearch/reference/2.1/modules-scripting.html and http://groovy-lang.org/syntax.html)
     *
     * Use this script when you need to add or delete a single value (int or long) in a list field.
     *
     * Mandatory params:
     * - "paramFieldname": name of the list field to modify
     * - "paramValue": value to add or delete from the field "paramFieldname"
     * - "paramAction", add ? "add" : "del"
     */
    long longparamValue = paramValue as long
    long[] longarray = ctx._source[paramFieldname] as long[]
    
    if(paramAction == "add") {
      if(longarray.contains(longparamValue) == false) {
        ctx._source[paramFieldname].add(longparamValue);
      }
    } else if(paramAction == "del") {
      if(longarray.contains(longparamValue) == true) {
        ctx._source[paramFieldname].removeAll(longparamValue)
      }
    }

(Sree2k) #4

Awesome, it works now. thanks!

Must be a problem with transport client and painless script.


(Nik Everett) #5

In Painless you can make a long constant by ending it in L. So 9000000000001L.

You are probably better off using params for the script so you don't compile a new script every time you have a new request. That'd look something like

"script": {
  "inline": "if (ctx.source.x.contains(params.to_add) {ctx.op='none'} else {ctx.source.x.add(params.to_add)}",
  "params": { "to_add": 9000000000001}
}

(Sree2k) #6

cool, it works with appending an L. thanks!


(system) #7

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