How to get a value of key value pair in an object in elasticsearch painless script

A partial mapping of one of my indices (in ES6.2) is as follows

"sdata": {
  "type": "object",
  "dynamic": true,
  "properties": {
    "xyz": {
      "dynamic": true,
      "properties": {}
    },
    "students": {
      "dynamic": true,
      "properties": {
        "name_age": {
          "dynamic": "true",
          "type": "object",
          "properties": {
          }
        },
        "school_id": {
          "type": "integer"
        }
      }
    }
  }
}

and one sample doc of that index is as follows:

{
  "sdata": {
      "xyz": {
          "abc": 0,
          "def": 0,
          "klm": null
      },
      "students": {
          "roll_age": {
              1021: 27,
              99271: 12,
              5119: 21,
          },
          "school_id": 12
      }
  }
}

I have a painless script in which my goal is to do a custom scoring calculation based on supplied student's roll number (that is a random number). For example, if
student roll is 99271, then it should return score 12

I tried to write a script in the following two ways - option1 and option2 below. None of them worked.

"script": {
  "params": {
    "student_roll": 99271
  },
  "source": """
    
    // option - 1
    if (doc['sdata.students.roll_age'].containsKey(params.student_roll)) {
      // how to return the value?
    }

    // option - 2
    int ilen = doc['sdata.students.roll_age'].length;
    for (int i = 0; i < ilen; i++) {
      if(doc['sdata.students.roll_age'][i] == params.student_roll) {
        return doc['sdata.students.roll_age'][i];
      }
    }

  """
}

Any idea how to get it through painless script?

Your sample document is not valid JSON. Did you mean for the keys inside roll_age to be strings?

{
  "sdata": {
    "xyz": {
      "abc": 0,
      "def": 0,
      "klm": null
    },
    "students": {
      "roll_age": {
        "1021": 27,
        "5119": 21,
        "99271": 12
      },
      "school_id": 12
    }
  }
}

If so, you can use the following Painless script to retrieve the values:

"script": {
  "params": {
    "student_roll": 99271
  },
  "source": """
return doc['sdata.students.roll_age.' + params.student_roll].value
"""
}
1 Like

Thank you @abdon ..yes my sample snippet was wrong, roll_age is string. It works now. Thank you :slight_smile: but is there any way to iterate key=>value pair in for loop?

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