App Search Boosts explained

Could someone please check if my current understanding of how boosts work in app search is correct.

I also cannot get a "script" to generate when using the search_explain api, on the proximity boosts. I wanted to do this to see how the boost is calculated in code. How would these look in that script format?

I already checked the following documentation: relevance tuning guide

Thanks,
Chenko

I also cannot get a "script" to generate when using the search_explain api, on the proximity boosts. I wanted to do this to see how the boost is calculated in code. How would these look in that script format?

The proximity boost is done differently.
Taking the proximity boost example from the documentation, we can use the search_explain API with the sample national-parks-demo engine:

curl -X GET 'http://localhost:3002/api/as/v1/engines/national-parks-demo/search_explain' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer private-[REDACTED]' \
-d '{
  "boosts": {
    "location": {
      "type": "proximity",
      "function": "linear",
      "center": "25.32, -80.93",
      "factor": 8
    }
  },
  "query": "old growth"
}'

If we take the Elasticsearch query from the response:


GET .ent-search-engine-documents-national-parks-demo/_search
{
  "query": {
    "bool": {
      "must": {
        "function_score": {
          "boost_mode": "sum",
          "score_mode": "sum",
          "query": {
            "bool": {
              "must": [
                {
                  "bool": {
                    "should": [
                      {
                        "multi_match": {
                          "query": "old growth",
                          "minimum_should_match": "1<-1 3<49%",
                          "type": "cross_fields",
                          "fields": [
                            "world_heritage_site^1.0",
                            "world_heritage_site.stem^0.95",
                            "world_heritage_site.prefix^0.1",
                            "world_heritage_site.joined^0.75",
                            "world_heritage_site.delimiter^0.4",
                            "description^2.4",
                            "description.stem^2.28",
                            "description.prefix^0.24",
                            "description.joined^1.8",
                            "description.delimiter^0.96",
                            "title^5.0",
                            "title.stem^4.75",
                            "title.prefix^0.5",
                            "title.joined^3.75",
                            "title.delimiter^2.0",
                            "nps_link^0.7",
                            "nps_link.stem^0.665",
                            "nps_link.prefix^0.07",
                            "nps_link.joined^0.525",
                            "nps_link.delimiter^0.28",
                            "states^2.8",
                            "states.stem^2.66",
                            "states.prefix^0.28",
                            "states.joined^2.1",
                            "states.delimiter^1.12",
                            "id^1.0"
                          ]
                        }
                      },
                      {
                        "multi_match": {
                          "query": "old growth",
                          "minimum_should_match": "1<-1 3<49%",
                          "type": "best_fields",
                          "fuzziness": "AUTO",
                          "prefix_length": 2,
                          "fields": [
                            "world_heritage_site.stem^0.1",
                            "description.stem^0.24",
                            "title.stem^0.5",
                            "nps_link.stem^0.07",
                            "states.stem^0.28"
                          ]
                        }
                      }
                    ]
                  }
                }
              ]
            }
          },
          "functions": [
            {
            "linear": {
              "location.location": {
                "origin": "25.32, -80.93",
                "scale": "1km"
              }
            },
            "weight": 8
            }
          ]
        }
      }
    }
  },
  "sort": [
    {
      "_score": "desc"
    },
    {
      "_doc": "desc"
    }
  ],
  "highlight": {
    "fragment_size": 300,
    "type": "plain",
    "number_of_fragments": 1,
    "order": "score",
    "encoder": "html",
    "require_field_match": false,
    "fields": {}
  },
  "size": 10,
  "from": 0,
  "timeout": "30000ms",
  "_source": [
    "visitors",
    "square_km",
    "world_heritage_site",
    "date_established",
    "description",
    "location",
    "id",
    "acres",
    "title",
    "nps_link",
    "states"
  ]
}

The proximity boost is a separate function that is being passed to the function_score query:

{
  "linear": {
    "location.location": {
      "origin": "25.32, -80.93",
      "scale": "1km"
    }
  },
  "weight": 8
}
1 Like

looks right!
to give more context, we always want to ensure that the score the script returns is positive, since Elasticsearch does not allow for negative scores - if the script score would return a negative value, Elasticsearch would return an error. That's why we always use Math.max(..., 0).

1 Like

Thanks for the confirmation and additional information!

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