Kibana painless scripted fields. Loop on array of objects

Hey ES Gurus,

I been trying to generate reports from es documents in kibana. Below is the sample

{
"customer" : 
"contact": 
{
"phones" : [
{
"category":"personal",
"number":"1111111111"
},
{
"category":"work",
"number":"2222222222"
}
]

}

}

When i use painless script as below

doc["customer.contact.phones.category.keyword"].values + ':' +doc["customer.contact.phones.number.keyword"].values 

The output goes as

["personal","work"] , ["111111111","2222222222"] in the discover module.

I am anticipating the output as below and have implemented painless script

["personal:"1111111111"] ,
["work":"2222222222"]

Then i tried using painless loop as below in the scripted field text box and seeing the error. Please help me out

for(int i=0; doc["customer.contact.phones.number.keyword"].length;i++){
doc["customer.contact.phones.category.keyword"][i].value +':'+ 
doc["customer.contact.phones.number.keyword"][i]
.value}
Error: Request to Elasticsearch failed: {"error":{"root_cause":[{"type":"script_exception","reason":"compile error","script_stack":["... r.keyword\"].length;i++){\ndoc[\"LiveFeed.customer.pr ...","                             ^---- HERE"],"script":"for(int i=0; doc[\"customer.contact.phones.number.keyword\"].length;i++){\ndoc[\"customer.contact.phones.category.keyword\"][i].value +':'+ \ndoc[\"customer.contact.phones.number.keyword\"][i]\n.value}","lang":"painless"}],"type":"search_phase_execution_exception","reason":"all shards failed","phase":"query","grouped":true,"failed_shards":[{"shard":0,"index":"cem-profile-index","node":"rN4VSEjiREi6T-LofTIH2A","reason":{"type":"script_exception","reason":"compile error","script_stack":["... r.keyword\"].length;i++){\ndoc[\"LiveFeed.customer.pr ...","                             ^---- HERE"],"script":"for(int i=0; doc[\"customer.contact.phones.number.keyword\"].length;i++){\ndoc[\"customer.contact.phones.category.keyword\"][i].value +':'+ \ndoc[\"customer.contact.phones.number.keyword\"][i]\n.value}","lang":"painless","caused_by":{**"type":"illegal_argument_exception","reason":"Not a statement."**}}}]},"status":500}

have you tried something like:

def l = new ArrayList();

for(int i=0; doc["customer.contact.phones.number.keyword"].values.length;i++){
  l.add(doc["customer.contact.phones.category.keyword"].values[i] +':'+ doc["customer.contact.phones.number.keyword"].values[i])
}

return l;

Thanks for the reply Peter. I tried and seeing the error below.

"lang":"painless","caused_by":{"type":"wrong_method_type_exception","reason":"cannot convert MethodHandle(List)int to (Object)boolean"}}}]},"status":500}

Looks like the return type to be boolean.

try return l.toArray(); ? also what type of scripted field is it ?

The error still the same after l.toArray();

Below is the screenshot of the same. I see only few datatypes

string, number, boolean , date in type dropdown. After checking elastic search logs, ES itself not liking the script and throwing the exception

Caused by: java.lang.invoke.WrongMethodTypeException: cannot convert MethodHandle(List)int to (Object)boolean

sorry, the if statement is broken ....

for(int i=0; i < doc["customer.contact.phones.number.keyword"].values.length;i++){

or if you are using older version of es something like this should work:

def l = new ArrayList();

for(int i=0; i < params._source.customer.contact.phones.length;i++){
  l.add(params._source.customer.contact.phones[i].category +':'+ params._source.customer.contact.phones[i].number])
}

return l.toArray();
1 Like

Thanks Peter, i am able to get it worked. I see the desired output now.Have a good one

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