[Painless script] i_o_exception: can not write type [class java.lang.StringBuffer]


(Junkoshimane) #1

Hi all,

I'm new to painless scripting. I faced the exception as described in the above title. Would you please tell my why?

1.All documents

 [adminadmin@js ~]$ cat query_all.json
 {
   "query" : { "match_all": {} }
 }
 [adminadmin@js ~]$ curl -X GET "localhost:9200/span/_search?pretty" -H 'Content-Type: application/json' -d @query_all.json
 {
   "took" : 13,
   "timed_out" : false,
   "_shards" : {
     "total" : 5,
     "successful" : 5,
     "skipped" : 0,
     "failed" : 0
   },
   "hits" : {
     "total" : 3,
     "max_score" : 1.0,
     "hits" : [
       {
         "_index" : "span",
         "_type" : "docs",
         "_id" : "2",
         "_score" : 1.0,
         "_source" : {
           "textfield" : "jjj iii hhh ggg fff eee ddd ccc bbb aaa"
         }
       },
       {
         "_index" : "span",
         "_type" : "docs",
         "_id" : "1",
         "_score" : 1.0,
         "_source" : {
           "textfield" : "aaa bbb ccc ddd eee fff ggg hhh iii jjj"
         }
       },
       {
         "_index" : "span",
         "_type" : "docs",
         "_id" : "3",
         "_score" : 1.0,
         "_source" : {
           "textfield" : "bbb eee hhh iii jjj ggg fff ddd aaa ccc"
         }
       }
     ]
   }
 }

1.Painless script: I'd like to insert "," in front of "ccc".

 [adminadmin@js painless_script]$ cat pain_src_eng.json
 {
   "query": {
     "match_all": {}
   },
   "script_fields": {
     "test1": {
       "script": {
         "lang": "painless",
         "source": "
           String text = params._source.textfield;
           StringBuffer sb = new StringBuffer(text);
           String delim = ',';
           String user = 'ccc';
 
           int idx = 0;
           int result = 0;
           result = sb.indexOf(user, idx);
           sb.insert(result, delim);
         "
         }
       }
     }
   }
 }

1.Exception

 [adminadmin@js painless_script]$ curl -X GET "localhost:9200/span/_search?pretty" -H 'Content-Type: application/json' -d @pain_src_eng.json
 {
   "took" : 15,
   "timed_out" : false,
   "_shards" : {
     "total" : 5,
     "successful" : 2,
     "skipped" : 0,
     "failed" : 3,
     "failures" : [
       {
         "shard" : 2,
         "index" : "span",
         "node" : "U3cBA7fHTliy1rR090O3Fg",
         "reason" : {
           "type" : "i_o_exception",
           "reason" : "can not write type [class java.lang.StringBuffer]"
         }
       }
     ]
   },
   "hits" : {
     "total" : 3,
     "max_score" : 1.0,
     "hits" : [ ]
   }
 }

1.Script works without insert API.

 [adminadmin@js painless_script]$ curl -X GET "localhost:9200/span/_search?pretty" -H 'Content-Type: application/json' -d @pain_src_eng.json
 {
   "took" : 10,
   "timed_out" : false,
   "_shards" : {
     "total" : 5,
     "successful" : 5,
     "skipped" : 0,
     "failed" : 0
   },
   "hits" : {
     "total" : 3,
     "max_score" : 1.0,
     "hits" : [
       {
         "_index" : "span",
         "_type" : "docs",
         "_id" : "2",
         "_score" : 1.0,
         "fields" : {
           "test1" : [
             28
           ]
         }
       },
       {
         "_index" : "span",
         "_type" : "docs",
         "_id" : "1",
         "_score" : 1.0,
         "fields" : {
           "test1" : [
             8
           ]
         }
       },
       {
         "_index" : "span",
         "_type" : "docs",
         "_id" : "3",
         "_score" : 1.0,
         "fields" : {
           "test1" : [
             36
           ]
         }
       }
     ]
   }
 }

(Jack Conradson) #2

When using a script field, the value that is returned must be a type that can be converted into a usable value -- String, number, etc. In this case, the insert method returns a StringBuffer which isn't a value that can be parsed effectively. If you add the line return sb.toString() to the end of the script I think this will work as intended.


(Junkoshimane) #3

Hi Jack,

Thank you for your reply and cooperation.
.
After I added the line "return sb.toString()" to the end of the script, it works as expected.


(system) #4

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