-1

Below is mapping which i have

{
  "defaultBoostValue":1.01,
  "boostDetails": [
    {
      "Type": "Type1",
      "value": 1.0001
    },
    {
      "Type": "Type2",
      "value": 1.002
    },
    {
      "Type": "Type3",
      "value": 1.0005
    }
  ]
}

I want to apply boost type based on type , so if boostType is Type3 then boostFactor should be 1.0005, and if it does not have that boostType, it should apply "defaultBoostValue" as boost below is the query which i have tried

{
  "query": {
    "function_score": {
      "boost_mode": "multiply",
      "functions": [
        {
          "filter": {
            "match": {
              "boostDetails.Type": "Type1"
            }
          },
          "field_value_factor": {
            "field": "boostDetails.value",
            "factor": 1,
            "missing": 1
          }
        }
      ]
    }
  }
}

it is not working as expected as boostDetails is array of object, how can we apply filter on such case

1 Answer 1

1

You could use a Script Score function_score query

{
  "query": {
    "function_score": {
      "boost_mode": "multiply",
      "functions": [
        {
          "filter": {
            "match": {
              "boostDetails.Type": "Type1"
            }
          },
          "script_score": {
            "script": {
              "source": """
                double findBoost(Map params_copy) {
                    for (def group : params_copy._source.boostDetails) {
                        if (group['Type'] == params_copy.preferredBoostType ) {
                            return group['value'];
                        }
                    }
                    return params_copy._source['defaultBoostValue'];
                }
                
                return findBoost(params)
              """,
              "params": {
                "preferredBoostType": "Type1"
              }
            }
          }
        }
      ]
    }
  }
}

but keep in mind that if this particular boost type (Type1) does not exist in a given document, the filter of your function_score query will prevent this script from activation -> the defaultBoostValue won't be defaulted to at all.

So what I'd recommend instead is using a match_all filter instead and of course keeping the preferredBoostType:

{
  "query": {
    "function_score": {
      "boost_mode": "multiply",
      "functions": [
        {
          "filter": {
            "match_all": {}                          <---
          },
          "script_score": {
            "script": {
              "source": """

                ...

              """,
              "params": {
                "preferredBoostType": "Type1"
              }
            }
          }
        }
      ]
    }
  }
}

BTW, if your boostDetails array is not of type nested, you'll probably encounter unexpected and seemingly results as explained here and here.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.