1
votes

i am trying to do a search with custom functions to modify document score. I have a mapping with specialities stored inside a hospital and every speciality has a priority with it: Something like:

hospital:{
  name: 'Fortis', 
  specialities: [
   {
   name: 'Cardiology',
   priority: 10
  },
   {
   name: 'Oncology',
   priority: 15
  }
]
}

Now i have a function score :

functions: [{
     filter: {terms: {'specialities.name' => params[:search_text]}},
     script_score: {script: "_score * doc['specialities.priority'].value"}
                        },

I have a filter query to match the search text to any speciality. Like if i search Oncology, it will match and then I have specified a script_score to take priority of that speciality and add it to final score of document.

But, it is taking the priority of the first speciality it encounters that is 10 and a score of 1 for the filter matched and the end score is 11 not 21 (priority of oncology + 1 for filter match)

1

1 Answers

1
votes

I solved it using nested mapping in elasticsearch. Lucene internally has no concept of storing object mappings by default, so if I am looking to store priority for every speciality I should have a mapping like this:

hospital: {
  properties: {
    specialities: {
      type: nested,
      properties: {
        name: {
          type: 'string'
        }priority: {
          type: 'long'
        }
      }
    }
  }
}

Reference: https://www.elastic.co/guide/en/elasticsearch/reference/2.0/nested.html

After that, I was able to define function score with nested query and my query looks like this:

  "query": {
    "filtered": {
      "query": {
        "bool": {
          "must": [
            {
              "nested": {
                "path": "specialities",
                "query": {
                  "function_score": {
                    "score_mode": "sum",
                    "boost_mode": "sum",
                    "filter": {
                      "terms": {
                        "specialities.name.raw": ["Oncology"]
                      }
                    },
                    "functions": [
                      {
                        "field_value_factor": {
                          "field": "specialities.priority"
                        }
                      }
                    ]
                  }
                }
              }
            }
          ]
        }
      }
    }
  }