Terms filter not receiving a hit within a function score

I am relatively new to Elasticsearch and am building a function score query to find vehicles that may be of interest to our users. We have a field called "make" which holds the brand of the car manufacturer such as "BMW".

I have a function score which includes the make filters as a component like this:

      "functions": [
        {
          "filter": {
            "term": {
              "make": 
                "BMW"
            }
          },
          "weight": 3
        },
        {
          "filter": {
            "match": {
              "country": "USA"
            }
          },
          "weight": 3
        }

When I run the function score query with this configuration, it does not apply the term filter weight to documents with make = "BMW". However if I change it to a match_phrase filter, it returns them with the proper weight applied.

Why is the "term" filter preventing the function score from providing a hit on that function?

When I make a simple query outside of the function score, such as the one below, it returns documents:

    {
      "query": {
        "term": {
          "make": "bmw"
        }
      }
    }

Let me provide a full function score sample just for this:

{
  "explain":true,
  "query": {
    "function_score": {
      "query": {
        "bool": {
          "must_not": [
            {
              "term": {
                "likes": "5b07851c914d840014cf24e4"
              }
            },
            {
              "term": {
                "views": "5b07851c914d840014cf24e4"
              }
            },
            {
              "term":{
                "owner": "5b07851c914d840014cf24e4"
              }
            },
            {
              "term": {
                "privacy": "1"
              }
            }
          ]
        }
      },
      "score_mode": "sum",
      "boost_mode": "replace",
      "functions": [
        {
          "filter": {
            "term": {
              "make": 
                "BMW"
            }
          },
          "weight": 3
        }
      ]
    }
  }
}

Additionally here is the mapping configuration for this field:

      "make": {
        "type": "text",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
          }
        }

This should have been an easy one for all of you experts!

Since the field is set as type "text", the tokenizer sets the indexed value as "bmw". Since the terms query is a keyword search, I was trying to query "BMW" against "bmw", which is why it did not return the results.

When I run the same terms query with lowercase "bmw", it gets hits.

@Stephen_Kneubuehl

You may want to use "make.keyword": "BMW". Your current query won't give you correct results if "make" value has multiple words like "Austin Martin" .

Also note when you use make.keyword, match is case sensitive. BMW will match but bmw won't. If you need case insensitive match you need to add "lowercase" filter to the normalizer on the keyword field.

Thanks so much @Vinayak_Sapre, after further research today I noticed as well that the mapping should support a keyword query, but I did not realize it required specification as "make.keyword" in the query. This is very helpful.

Understood also about multiple word values. Thank you for your insight.

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