Home > OS >  How to apply custom score to a search filed in Elastic Search
How to apply custom score to a search filed in Elastic Search

Time:11-01

I am making a search query in Elastic Search and I want to treat the fields the same when they match. For example if I search for field field1 and it matches, then the _score is increase by 10(for example), same for the field2.

I was tried function_score but it's not working. It throws an error.

"caused_by": {
    "type": "class_cast_exception",
    "reason": "class 
               org.elasticsearch.index.fielddata.plain.SortedSetDVOrdinalsIndexFieldData 
               cannot be cast to class 
               org.elasticsearch.index.fielddata.IndexNumericFieldData 
               (org.elasticsearch.index.fielddata.plain.SortedSetDVOrdinalsIndexFieldData 
               and org.elasticsearch.index.fielddata.IndexNumericFieldData are in unnamed 
               module of loader 'app')"
}

The query:

{
  "track_total_hits": true,
  "size": 50,
  "query": {
    "function_score": {
      "query": {
        "bool": {
          "must": [
            {
              "term": {
                "field1": {
                  "value": "Value 1"
                }
              }
            },
            {
              "term": {
                "field2": {
                  "value": "value 2"
                }
              }
            }
          ]
        }
      },
      "functions": [
        {
          "field_value_factor": {
            "field": "field1",
            "factor": 10,
            "missing": 0
          }
        },
        {
          "field_value_factor": {
            "field": "field2",
            "factor": 10,
            "missing": 0
          }
        }
      ],
      "boost_mode": "multiply"
    }
  }
}

CodePudding user response:

You can use function score with filter function to boost.

assuming that your mapping looks like the one below

{
  "mappings": {
    "properties": {
      "field_1": {
        "type": "keyword"
      },
      "field_2": {
        "type": "keyword"
      }
    }
  }
}

with documents

{"index":{}}
{"field_1": "foo", "field_2": "bar"}
{"index":{}}
{"field_1": "foo", "field_2": "foo"}
{"index":{}}
{"field_1": "bar", "field_2": "bar"}

you can use weight parameter to boost the documents matched for each query.

{
  "query": {
    "function_score": {
      "query": {
        "match_all": {}
      },
      "functions": [
        {
          "filter": {
            "term": {
              "field_1": "foo"
            }
          },
          "weight": 10
        },
        {
          "filter": {
            "term": {
              "field_2": "foo"
            }
          },
          "weight": 20
        }
      ],
      "score_mode": "multiply"
    }
  }
}

CodePudding user response:

You can refer below solution if you want to provide manual weight for different field in query. This will always replace highest weight field on top of your query response -

Elasticsearch query different fields with different weight

  • Related