Adding additional weight without matching

I want to be able to

  1. Match a subset of the index with a query_string query.
  2. Add additional weight to documents that match a set of post-evaluated criterias.

Example:

Let's say I have these two documents:

[
    {
        "Title": "lord of the rings 1",
        "Tags": ["book", "movie", "adventure"]
    },
    {
        "Title": "lord of the rings 2",
        "Tags": ["book", "adventure"]
    }
]

I make a search with this query:

{
  "query": {
    "function_score": {
      "query": {
        "query_string": {
          "fields": [
            "Title"
          ],
          "query": "lord of the rings adventure movie"
        }
      },
      "functions": [
        {
          "filter": {
            "match": {
              "Tags": {
                "query": "lord of the rings adventure movie"
              }
            }
          },
         "weight": 2.0
        }
      ]
    }
  }
}

The specific mappings/settings should not be relevant to this question, so I skipped them.

Question:
How do I make the match query inside the functionscore filter pay attention to how well the match query matches the query instead of just a boolean decision whether to apply the static weight or not? In this case, the first document is a better match, since it matches both tags (adveture, movie), whereas the second document only matches one of the tags (adventure), but they come out being equal matches because of the boolean nature of functionscore filters.

I can't move the match into the root query, as I don't want to include other documents with those tags in the output, but I still want the most closely matched document to come first.

Maybe there is a completely different approach to this issue that I'm just not aware of.

Any help is appreciated.

function_score query accepts only a single main query, all other queries inside functions can only be filters with a just boolean decision.

One way you can structure your query is to do a boolean query with must clause as your main query, and should clause as your additional query, something like this:

{
  "query": {
    "bool": {
      "must": {
        "query_string": {
          "fields": [
            "Title"
          ],
          "query": "lord of the rings adventure movie"
        }
      },
      "should": {
        "match": {
          "Tags": {
            "query": "lord of the rings adventure movie"
          }
        }
      }
    }
  }
}

Hi mayya - thanks for the reply

I could construct the query that way, but that would lead to the match on the Tags field in the should-clause pulling more documents into the resultset, if a Tag happens to match any of the terms in the query.

I'm trying to implement the same behavior as the rescore functionality, but in a way that would always take the entire resultset into consideration and not just a defined window.

the match on the Tags field in the should-clause pulling more documents into the results set

No, this will not happen. The results set is determined by the must clause; should clause is used only for adding extra points to scores.

1 Like

Hi mayya

This works exactly the way you describe and solves the problem beautifully.
Re-reading the bool-query documentation makes this clear as well.

Thank you!

1 Like

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