I want to do a painless script that will get the max groupe_an value filtered by an. I have indexed as follows, without nesting. Then I add multi-valued data in an array. But I somehow lose the consistency of the order in the two list of fields in the painless script. Using the index k is not nice, I am just experimenting. I would have liked to iterate on the objects but could not find a way to do that, something like
for (item in doc['micro.ans'])
but I get
"caused_by" : {
"type" : "illegal_argument_exception",
"reason" : "Extraneous for each loop."
}
I may have to index differently. What would be the good solution in terms of index and in terms of painless script ? Thank you.
PUT test-500
{
"mappings": {
"properties": {
"micro" : {
"properties": {
"ans" : {
"properties" : {
"an" : {
"type" : "keyword"
},
"groupe_an" : {
"type": "float"
}
}
}
}
}
}
}
}
PUT test-500/_doc/1
{
"micro" : {
"ans" : [
{"an": "686660", "groupe_an" : 14.0},
{"an": "439750", "groupe_an" : 6.0}
]
}
}
PUT test-500/_doc/2
{
"micro" : {
"ans" : [
{"an": "286660", "groupe_an" : 100.0},
{"an": "239750", "groupe_an" : 200.0}
]
}
}
GET test-500/_search
{
"query": {
"script_score" : {
"query" : {
"match_all": {}
},
"script" : {
"source" : """
double max = 0;
int k=0;
List ans = doc['micro.ans.an'];
List groupe_ans = doc['micro.ans.groupe_an'];
for (an in ans) {
if (an == params.queried_an && groupe_ans[k]>max) {
max=groupe_ans[k]} k=k+1
}
return max
""",
"lang" : "painless",
"params" : {
"queried_an" : "239750"
}
}
}
}
}
I ended up using a concatenation of the two fields into a single keyword typed field:
PUT test-2003
{
"mappings": {
"properties": {
"micro" : {
"properties": {
"an_groupe" : {
"type" : "keyword"
}
}
}
}
}
}
PUT test-2003/_doc/1
{
"micro" : {
"an_groupe" : [
"686660|14.0",
"439750|6.0"
]
}
}
PUT test-2003/_doc/2
{
"micro" : {
"an_groupe" : [
"68666022|100.0",
"43975022|200.0"
]
}
}
GET test-2003/_search
{
"query": {
"script_score" : {
"query" : {
"match_all": {}
},
"script" : {
"source" : """
double max = 0;
for (an_groupe in doc['micro.an_groupe']) {
String[] splitted = an8_groupe.splitOnToken("|");
double groupe_val = Double.parseDouble(splitted[1]);
for (queried_an in params.queried_ans) {
if (splitted[0] == queried_an && groupe_val > max) {
max = groupe_val
}
}
}
return max
""",
"lang" : "painless",
"params" : {
"queried_ans" : ["68666022", "43975022", "439750"]
}
}
}
}
}