Search code examples
elasticsearchelasticsearch-painless

Elasticsearch Painless script get nested field by value?


I want to compute the score of my query on elasticsearch based on a nested field value. Here is an example of my document:

{
  "title": "Mr",
  "first_name": "Barry",
  "last_name": "White",
  "experiences": [
     {
       "name": "parachute",
       "values": {
           "last_year": 4,
           "older": 12
       }
    },
    {
       "name": "base jump",
       "values": {
           "last_year": 2,
           "older": 1
       }
    }
   ]
}

What I want is filter and rank a query according to number of experiences and range (last year values are more important). The problem is: how can I get the value of filtered experience?

here is a simplified version of my query:

{
"query" :{
    "nested": {
        "path": "experiences",
        "query":{
            "function_score" : {
                "functions": [
                    {
                        "filter": {"term": { "experiences.name": "parachute"} },
                        "script_score" : {
                            "script" : {
                              "lang": "painless",
                              "inline": "_score * doc['experiences.values.older'].value" //Here I want to get the "older" value of "parachute": 12
                            }
                        }
                    }
                ]
             }

        }
    }
}
}

Hope there's a way to solved this...

Thanks in advance for your help


Solution

  • I finally managed to solve this problem thanks to some help from the official elasticsearch IRC channel. I had to change a little bit the document mapping:

    • remove "values"
    • set "last_year" and "older" as root values of each experience

    and that's it. So here is the final query:

    {
        "query" :{
            "nested": {
                "path": "experiences",
                "query":{
                    "function_score" : {
                        "query":{
                            "term": { "experiences.name": "parachute"}
                        },
                        "functions": [
                            {
                                "field_value_factor": {
                                    "field": "experiences.older",
                                    "factor": 1,
                                    "missing": 1
                                }
                            },{
                                "field_value_factor": {
                                    "field": "experiences.last_year",
                                    "factor": 2,
                                    "missing": 1
    
                                }
                            }
                        ],
                        "score_mode": "sum"
                    }
                }
            }
        }
    }