# Count how many terms match document

**URL:** <https://discuss.elastic.co/t/count-how-many-terms-match-document/96222>\
**Category:** Elasticsearch\
**Created:** [August 8, 2017, 8:42am UTC](https://discuss.elastic.co/t/count-how-many-terms-match-document/96222 "2017-08-08T08:42:28Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![ebuildy](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/ebuildy/32/6070_2.png) [@ebuildy](https://discuss.elastic.co/u/ebuildy)\
**Post date:** [August 8, 2017, 8:42am UTC](https://discuss.elastic.co/t/count-how-many-terms-match-document/96222/1 "2017-08-08T08:42:28Z")

</div>

My document have an array of string:

`"categories" : ["A", "B", "C"]`

I query like this:

```
POST /topic/_search?explain=true
{
   "query": {
            "terms": {
               "categories": [
                  "yoga",
                  "meditation"
               ]
            }
   }
}

```

It works fine but the score is computed via TF/IDF (1,4 \* 1,9 ....), I would like to have a score that indicate how many categories are matching (1 / 2 / 3 etc..).

Tried constant\_score, but not working with terms.

---

<div class="post-metadata">

**Author:** ![s1monw](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/s1monw/32/3637_2.png) [@s1monw](https://discuss.elastic.co/u/s1monw)\
**Post date:** [August 11, 2017, 9:28am UTC](https://discuss.elastic.co/t/count-how-many-terms-match-document/96222/2 "2017-08-11T09:28:24Z")

</div>

did you try constant score and instead of using terms use one optional boolean clause per category with a `term` (note singular) query? This should work just fine I guess.

something like this:

```auto
POST /topic/_search?explain=true
{
   "query": {
            "bool": {
                "should" : [
                  {"constant_score" : { "filter" : { "term" : { "categories" : "yoga" } } } } ,
                  {"constant_score" : { "filter" : { "term" : { "categories" : "meditation" } } } }
               ]
            }
   }
}

```

---

<div class="post-metadata">

**Author:** ![ebuildy](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/ebuildy/32/6070_2.png) [@ebuildy](https://discuss.elastic.co/u/ebuildy)\
**Post date:** [August 12, 2017, 2:01pm UTC](https://discuss.elastic.co/t/count-how-many-terms-match-document/96222/3 "2017-08-12T14:01:26Z")

</div>

Yeah, this is working, but I prefer rely on Lucene tokenizer, so I could get the tokens via ES API and do that, this is a good approach if there is no another way.

I know this is possible to change the similarity algo. via ES settings, is not possible to change / tune TF/IDF algo also ?

---

<div class="post-metadata">

**Author:** ![s1monw](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/s1monw/32/3637_2.png) [@s1monw](https://discuss.elastic.co/u/s1monw)\
**Post date:** [August 14, 2017, 8:26am UTC](https://discuss.elastic.co/t/count-how-many-terms-match-document/96222/4 "2017-08-14T08:26:13Z")

</div>

> [@ebuildy](#):
>
> Yeah, this is working, but I prefer rely on Lucene tokenizer, so I could get the tokens via ES API and do that, this is a good approach if there is no another way.

I am not sure what you mean, you used `terms` in your example.. are you refrerring to lowercaseing etc? You can use `match` query instead in the same example and you should be fine?

---

<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 11, 2017, 8:26am UTC](https://discuss.elastic.co/t/count-how-many-terms-match-document/96222/5 "2017-09-11T08:26:16Z")

</div>

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