How to avoid field_value_factor on 'must' clause

Hi, running the ELK stack on the Elastic cloud, I've defined a search template that has the following query:

"query": {
  "function_score": {
    "functions": [
      {
        "field_value_factor": {
          "field": "marketcap",
          "missing": 1,
          "modifier": "log1p"
        }
      }
    ],
    "query": {
      "bool": {
        "should": [
          {
            "multi_match": {
              "fields": [
                "name",
                "symbol^3"
              ],
              "query": "{{query_string}}",
              "type": "phrase_prefix"
            }
          },
          {
            "multi_match": {
              "fields": [
                "name"
              ],
              "fuzziness": "auto",
              "query": "{{query_string}}"
            }
          },
          {
            "match_phrase": {
              "symbol": {
                "boost": 3,
                "query": "{{query_string}}"
              }
            }
          },
        ]
      }
    }
  }
}

which scores the name and symbol fields of the document, and then adds score according to the field marketcap, in the form of math's log function.

I want to add a filter on field isEnabled so only documents with value true gets returned.

I tried adding it to the bool clause, under must, but then, the function_score gets applied to all of the documents, and not only to the results in the should clause (which makes sense).

how can get the desired result, which is filtering out all documents with isEnabled set to false but only use the marketcap score on the results of the should clause?

thanks!

Hi @blinker1

Did you apply the filter using the bool-filter? Show your query using the filter.

using the filter (added a must in the bool section):

"query": {
  "function_score": {
    "functions": [
      {
        "field_value_factor": {
          "field": "marketcap",
          "missing": 1,
          "modifier": "log1p"
        }
      }
    ],
    "query": {
      "bool": {
        "must": {
          "match": {
              "isEnabled": true
          }
        },
        "should": [
          {
            "multi_match": {
              "fields": [
                "name",
                "symbol^3"
              ],
              "query": "{{query_string}}",
              "type": "phrase_prefix"
            }
          },
          {
            "multi_match": {
              "fields": [
                "name"
              ],
              "fuzziness": "auto",
              "query": "{{query_string}}"
            }
          },
          {
            "match_phrase": {
              "symbol": {
                "boost": 3,
                "query": "{{query_string}}"
              }
            }
          },
        ]
      }
    }
  }
}

Try this:

If you filter the fields to keyword type it is always good to use filter context.

{
  "query": {
  "function_score": {
    "functions": [
      {
        "field_value_factor": {
          "field": "marketcap",
          "missing": 1,
          "modifier": "log1p"
        }
      }
    ],
    "query": {
      "bool": {
        "filter": {
          "term": {
            "isEnabled": true
          }
        },
        "should": [
          {
            "multi_match": {
              "fields": [
                "name",
                "symbol^3"
              ],
              "query": "{{query_string}}",
              "type": "phrase_prefix"
            }
          },
          {
            "multi_match": {
              "fields": [
                "name"
              ],
              "fuzziness": "auto",
              "query": "{{query_string}}"
            }
          },
          {
            "match_phrase": {
              "symbol": {
                "boost": 3,
                "query": "{{query_string}}"
              }
            }
          }
        ]
      }
    }
  }
}
}

with filter and term now, documents that didn't match the should clause are returned with score 0.
essentially, the whole index is returned. (with score 0). previously, using only the should clause returned only matching documents.

    "hits": {
        "total": {
            "value": 9306,
            "relation": "eq"
        },
        "max_score": 0.0,
        ...
     }

any clues to what can be done next?

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