# Only match if all tokens of an indexed field are included in the search query in any order

**URL:** https://discuss.elastic.co/t/only-match-if-all-tokens-of-an-indexed-field-are-included-in-the-search-query-in-any-order/305520
**Category:** Elasticsearch
**Created:** [May 24, 2022, 3:05pm UTC](https://discuss.elastic.co/t/only-match-if-all-tokens-of-an-indexed-field-are-included-in-the-search-query-in-any-order/305520 "2022-05-24T15:05:12Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![SwonVIP](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/swonvip/32/106103_2.png) [@SwonVIP](https://discuss.elastic.co/u/SwonVIP)
#### Post date: [May 24, 2022, 3:05pm UTC](https://discuss.elastic.co/t/only-match-if-all-tokens-of-an-indexed-field-are-included-in-the-search-query-in-any-order/305520/1 "2022-05-24T15:05:12Z")

</div>

Dear Elasticsearch Community,

currently trying to solve an use-case of a reverse AND condition on user search queries where all tokens have to be included in an indexed field in order to match a certain document.

**Example:**

Indexed documents have a property field with multiple tokens.

```auto
          "fieldXyz" : "quick brown fox"

```

The search should now only match if the user includes **ALL** tokens in his search request but the order should not matter.

So basically the following should **NOT** match:

"quick"  
"quick brown"  
"quick fox"  
...

However these should match:

"brown quick fox"  
"fox quick brown"  
...

I was thinking about counting the number of tokens via token\_count and adding another field on index time. However there is still the challenge of counting the tokens after analysis on query time (since stopwords and so on should be not counted). We cannot do this when processing the query on application level since the query is not analysed yet and calling the analyse API would create an additional round trip and increasing the search response time.

So is there a way to return the token count from maybe a custom analyzer and then match it to the field including the token count?

---

<div class="post-metadata">

### Author: ![vincenbr](https://avatars.discourse-cdn.com/v4/letter/v/8edcca/32.png) [@vincenbr](https://discuss.elastic.co/u/vincenbr)
#### Post date: [May 25, 2022, 8:26am UTC](https://discuss.elastic.co/t/only-match-if-all-tokens-of-an-indexed-field-are-included-in-the-search-query-in-any-order/305520/2 "2022-05-25T08:26:26Z")

</div>

Hi !  
my intuition for that would be to play with the score. Try to have a score calculated so that it can reflect a match, given your requirements.  
See "similarity" for score calculations: [Similarity module | Elasticsearch Guide [8.2] | Elastic](https://www.elastic.co/guide/en/elasticsearch/reference/8.2/index-modules-similarity.html)  
Simple example: Here we just give a score of 1 if every term in the field is in the query.  
And we filter out the docs that do not have a score of 1 (with `min_score`)

```auto
PUT toto
{
  "settings": {
    "number_of_shards": 1,
    "similarity": {
      "scripted_basic": {
        "type": "scripted",
        "script": {
          "source": """
          return doc.freq / doc.length;
          """
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "field1": {
        "type": "text",
        "analyzer": "english", 
        "similarity": "scripted_basic"
      }
    }
  }
}

PUT toto/_doc/1
{
  "field1" : "quick brown fox"
}

GET toto/_search?explain=true
{
  "query": {
    "match": {
      "field1": "Foxes Quick Brown"
    }
  }, 
  "min_score": 1
}

```

---

<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: [June 22, 2022, 8:27am UTC](https://discuss.elastic.co/t/only-match-if-all-tokens-of-an-indexed-field-are-included-in-the-search-query-in-any-order/305520/3 "2022-06-22T08:27:17Z")

</div>

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