# Score based on the matched multi-match counts

**URL:** <https://discuss.elastic.co/t/score-based-on-the-matched-multi-match-counts/144029>\
**Category:** Elasticsearch\
**Created:** [August 12, 2018, 10:10am UTC](https://discuss.elastic.co/t/score-based-on-the-matched-multi-match-counts/144029 "2018-08-12T10:10:54Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Peter\_Steenbergen](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/peter_steenbergen/32/22888_2.png) [@Peter\_Steenbergen](https://discuss.elastic.co/u/Peter_Steenbergen)\
**Post date:** [August 12, 2018, 10:10am UTC](https://discuss.elastic.co/t/score-based-on-the-matched-multi-match-counts/144029/1 "2018-08-12T10:10:54Z")

</div>

Hi,

I was wondering the following thing. How to get the count of the matching fields?  
Like if you have a query with boosting of some kind o following query.

```
GET hotels/_search
{
  "query": {
    "multi_match": {
      "query": "Spain",
      "fields": ["city.title^2", "country.title", "name^3"]
    }
  }
}

```

Lets say the name and country where a match. How to give back a count of 2 as a score?  
So the score is the field count that matched the query.

---

<div class="post-metadata">

**Author:** ![abdon](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/abdon/32/9195_2.png) [@abdon](https://discuss.elastic.co/u/abdon)\
**Post date:** [August 13, 2018, 8:04am UTC](https://discuss.elastic.co/t/score-based-on-the-matched-multi-match-counts/144029/2 "2018-08-13T08:04:48Z")

</div>

Hey Peter,

If you do not care about the the BM25 score, and just want a score based on the number of matching fields, you can switch to the [`boolean` similarity](https://www.elastic.co/guide/en/elasticsearch/reference/current/similarity.html). This will calculate a score of 0 or 1, depending on whether a field is a match or not.

You can apply boolean similarity per field in your mappings, or you can [make it the default similarity for your index](https://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules-similarity.html#default-base).

If you then combine that with the `multi_match` `most_fields` type, you will get an overall score that represents the total number of matching fields:

```auto
GET hotels/_search
{
  "query": {
    "multi_match": {
      "query": "Spain",
      "fields": ["city.title", "country.title", "name"],
      "type": "most_fields"
    }
  }
}

```

Note that this doesn't really work well with the boosting if you want to get a pure matching field count.

---

<div class="post-metadata">

**Author:** ![Peter\_Steenbergen](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/peter_steenbergen/32/22888_2.png) [@Peter\_Steenbergen](https://discuss.elastic.co/u/Peter_Steenbergen)\
**Post date:** [August 13, 2018, 8:22am UTC](https://discuss.elastic.co/t/score-based-on-the-matched-multi-match-counts/144029/3 "2018-08-13T08:22:18Z")

</div>

And if you want to use boosting, and the result getting back into an additional field with the matched counted fields? Is that an idea or option?

---

<div class="post-metadata">

**Author:** ![abdon](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/abdon/32/9195_2.png) [@abdon](https://discuss.elastic.co/u/abdon)\
**Post date:** [August 13, 2018, 12:11pm UTC](https://discuss.elastic.co/t/score-based-on-the-matched-multi-match-counts/144029/4 "2018-08-13T12:11:53Z")

</div>

Alright, so you want to have both the original BM25 scores using the boosts, as well as have Elasticsearch return the number of matching fields? I can think of one way of doing that, which requires your query to be written more verbosely.

First, rewrite your `multi_match` query to a [`dis_max` query](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-dis-max-query.html). The `dis_max` query is a more verbose way of writing a `multi_match` query of type `best_fields`. Your query can be rewritten into:

```auto
GET hotels/_search
{
  "query": {
    "dis_max": {
      "queries": [
        {
          "match": {
            "city.title": {
              "query": "Spain",
              "boost": 2
            }
          }
        },
        {
          "match": {
            "country.title": {
              "query": "Spain"
            }
          }
        },
        {
          "match": {
            "name": {
              "query": "Spain",
              "boost": 3
            }
          }
        }
      ]
    }
  }
}

```

Now, you can use [named queries](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-named-queries-and-filters.html) to let Elasticsearch tell you which of the sub queries actually matched each document. Using this feature, the `dis_max` query can be written as:

```auto
GET hotels/_search
{
  "query": {
    "dis_max": {
      "queries": [
        {
          "match": {
            "city.title": {
              "query": "Spain",
              "boost": 2,
              "_name": "1"
            }
          }
        },
        {
          "match": {
            "country.title": {
              "query": "Spain",
              "_name": "2"
            }
          }
        },
        {
          "match": {
            "name": {
              "query": "Spain",
              "boost": 3,
              "_name": "3"
            }
          }
        }
      ]
    }
  }
}

```

Each hit will now have an array of query names that matched this document:

```auto
"matched_queries": [
          "1",
          "2",
          "3"
        ]

```

Your application can easily get the size of this array to get the number of matching fields.

---

<div class="post-metadata">

**Author:** ![Peter\_Steenbergen](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/peter_steenbergen/32/22888_2.png) [@Peter\_Steenbergen](https://discuss.elastic.co/u/Peter_Steenbergen)\
**Post date:** [August 13, 2018, 12:34pm UTC](https://discuss.elastic.co/t/score-based-on-the-matched-multi-match-counts/144029/5 "2018-08-13T12:34:05Z")

</div>

Thanks Abdon, I will test this out tonight.

---

<div class="post-metadata">

**Author:** ![Peter\_Steenbergen](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/peter_steenbergen/32/22888_2.png) [@Peter\_Steenbergen](https://discuss.elastic.co/u/Peter_Steenbergen)\
**Post date:** [August 13, 2018, 3:57pm UTC](https://discuss.elastic.co/t/score-based-on-the-matched-multi-match-counts/144029/6 "2018-08-13T15:57:19Z")

</div>

Hi Abdon,

Is it possible to do something like this:

```
GET hotels/_search
{
    "query": {
        "function_score": {
            "query": {
              "dis_max": {
                "queries": [
                  {
                    "match": {
                      "city.title": {
                        "query": "Barcelona",
                        "boost": 2,
                        "_name": "1"
                      }
                    }
                  },
                  {
                    "match": {
                      "country.title": {
                        "query": "Spanje",
                        "_name": "2"
                      }
                    }
                  },
                  {
                    "match": {
                      "name": {
                        "query": "Hotel",
                        "boost": 3,
                        "_name": "3"
                      }
                    }
                  }
                ]
              }
            },
            "script_score" : {
                "script" : {
                  "source": "_source['matched_queries'].size()"
                }
            }
        }
    }
}

```

So wrapping it up in a function\_score, and then return the size() of the matched\_queries field?

---

<div class="post-metadata">

**Author:** ![abdon](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/abdon/32/9195_2.png) [@abdon](https://discuss.elastic.co/u/abdon)\
**Post date:** [August 13, 2018, 9:43pm UTC](https://discuss.elastic.co/t/score-based-on-the-matched-multi-match-counts/144029/7 "2018-08-13T21:43:32Z")

</div>

I don't think that this is possible.

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [September 10, 2018, 9:43pm UTC](https://discuss.elastic.co/t/score-based-on-the-matched-multi-match-counts/144029/8 "2018-09-10T21:43:36Z")

</div>

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