# Exact match search with permutation of words

**URL:** <https://discuss.elastic.co/t/exact-match-search-with-permutation-of-words/165643>\
**Category:** Elasticsearch\
**Created:** [January 24, 2019, 6:59pm UTC](https://discuss.elastic.co/t/exact-match-search-with-permutation-of-words/165643 "2019-01-24T18:59:24Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![ankur\_singla](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/ankur_singla/32/45612_2.png) [@ankur\_singla](https://discuss.elastic.co/u/ankur_singla)\
**Post date:** [January 24, 2019, 6:59pm UTC](https://discuss.elastic.co/t/exact-match-search-with-permutation-of-words/165643/1 "2019-01-24T18:59:24Z")

</div>

Hi guys

I am kinda stuck with a problem in elasticsearch. I want to apply exact match search with a permutation of words.

Suppose I have a doc with text **"paper boat"** & I want to apply exact search in such a way that it should come in response when query with **"paper boat" & "boat paper"**

More examples

```
           **Text**  **valid search values**
> "hell boy" "hell boy", "boy hell"
> "apple pie" "pie apple", "apple pie"

```

Is there any analyzer or anything to solve this problem. Please help me out on this.

---

<div class="post-metadata">

**Author:** ![dadoonet](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/dadoonet/32/137187_2.png) [@dadoonet](https://discuss.elastic.co/u/dadoonet)\
**Post date:** [January 24, 2019, 7:15pm UTC](https://discuss.elastic.co/t/exact-match-search-with-permutation-of-words/165643/2 "2019-01-24T19:15:45Z")

</div>

This is the default behavior unless I don't understand the problem.

---

<div class="post-metadata">

**Author:** ![ankur\_singla](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/ankur_singla/32/45612_2.png) [@ankur\_singla](https://discuss.elastic.co/u/ankur_singla)\
**Post date:** [January 25, 2019, 4:04am UTC](https://discuss.elastic.co/t/exact-match-search-with-permutation-of-words/165643/3 "2019-01-25T04:04:08Z")

</div>

In my understanding in default behaviour i will get result of **"apple pie"** from **"apple"** and **"pie"** search also but i want exact string match such that **"pie apple"** & **"apple pie"** should be only valid search strings for **"apple pie"** text ( **"apple"** and **"pie"** not valid for **"apple pie"** in my case).

---

<div class="post-metadata">

**Author:** ![dadoonet](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/dadoonet/32/137187_2.png) [@dadoonet](https://discuss.elastic.co/u/dadoonet)\
**Post date:** [January 25, 2019, 4:55am UTC](https://discuss.elastic.co/t/exact-match-search-with-permutation-of-words/165643/4 "2019-01-25T04:55:54Z")

</div>

I believe you can use a phrase search with slop = 2. See [https://www.elastic.co/guide/en/elasticsearch/reference/6.5/query-dsl-match-query-phrase.html](https://www.elastic.co/guide/en/elasticsearch/reference/6.5/query-dsl-match-query-phrase.html)

---

<div class="post-metadata">

**Author:** ![ankur\_singla](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/ankur_singla/32/45612_2.png) [@ankur\_singla](https://discuss.elastic.co/u/ankur_singla)\
**Post date:** [January 27, 2019, 10:40am UTC](https://discuss.elastic.co/t/exact-match-search-with-permutation-of-words/165643/5 "2019-01-27T10:40:10Z")

</div>

> [@dadoonet](#):
>
> slop

It will return the response with a single token search also for example-  
Text **"apple pie"** will break into two tokens [**"apple"** , **"pie"**] & if I trying to search using **match\_phrase query** with any of the token( **"apple"** or **"pie"** ), it will return the text **"apple pie"** which is not valid for my use-case. Only valid strings for search in my use-case are [**"apple pie"** , **"pie apple"**] for text **"apple pie"**.

In my use-case, all tokens of text are mandatory for the search but tokens can be in reverse order or any order.

---

<div class="post-metadata">

**Author:** ![farshad](https://avatars.discourse-cdn.com/v4/letter/f/bbe5ce/32.png) [@farshad](https://discuss.elastic.co/u/farshad)\
**Post date:** [February 14, 2019, 6:12am UTC](https://discuss.elastic.co/t/exact-match-search-with-permutation-of-words/165643/6 "2019-02-14T06:12:07Z")

</div>

You can split the texts into individual tokens and use a must query with all these tokens

---

<div class="post-metadata">

**Author:** ![ankur\_singla](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/ankur_singla/32/45612_2.png) [@ankur\_singla](https://discuss.elastic.co/u/ankur_singla)\
**Post date:** [February 15, 2019, 7:31pm UTC](https://discuss.elastic.co/t/exact-match-search-with-permutation-of-words/165643/7 "2019-02-15T19:31:56Z")

</div>

But it must come in response only when all tokens match not any.

means for keywords - "apple", "pie"

valid strings: "apple pie is good", "good apple pie"

invalid strings: "pie is bad", "apple is bad"

---

<div class="post-metadata">

**Author:** ![farshad](https://avatars.discourse-cdn.com/v4/letter/f/bbe5ce/32.png) [@farshad](https://discuss.elastic.co/u/farshad)\
**Post date:** [February 16, 2019, 6:28am UTC](https://discuss.elastic.co/t/exact-match-search-with-permutation-of-words/165643/8 "2019-02-16T06:28:37Z")

</div>

When you use two conditions(one for apple and one for pie) in a must it needs both query be matched

---

<div class="post-metadata">

**Author:** ![ankur\_singla](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/ankur_singla/32/45612_2.png) [@ankur\_singla](https://discuss.elastic.co/u/ankur_singla)\
**Post date:** [February 16, 2019, 8:01am UTC](https://discuss.elastic.co/t/exact-match-search-with-permutation-of-words/165643/9 "2019-02-16T08:01:40Z")

</div>

yes but if i have only one of the term either "apple" or "pie" in search string then also it ("apple", "pie") will be matched which I don't want.

My condition is that when search string contains both terms ("apple" and "pie") only then it should match.

e.g.

for "apple pie" indexed terms

when I search for string "apple is good" it should not matched cause it does not contains both terms "apple" & "pie".

But for search string "apple is good pie" it should match cause it is having both "apple" & "pie" .

---

<div class="post-metadata">

**Author:** ![dadoonet](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/dadoonet/32/137187_2.png) [@dadoonet](https://discuss.elastic.co/u/dadoonet)\
**Post date:** [February 16, 2019, 8:16am UTC](https://discuss.elastic.co/t/exact-match-search-with-permutation-of-words/165643/10 "2019-02-16T08:16:58Z")

</div>

But in your last example your documents should not match because they don't contain "is" and "good".

---

<div class="post-metadata">

**Author:** ![ankur\_singla](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/ankur_singla/32/45612_2.png) [@ankur\_singla](https://discuss.elastic.co/u/ankur_singla)\
**Post date:** [February 16, 2019, 8:54am UTC](https://discuss.elastic.co/t/exact-match-search-with-permutation-of-words/165643/11 "2019-02-16T08:54:54Z")

</div>

No, It should be matched since my string contains both terms of the indexed document which is "apple" & "pie".

e.g.  
"apple pie" - is indexed doc in ES  
{"search\_term": "apple pie", "category": "apple product"} - indexed doc

1.query:{  
match:{"search\_term": "apple is good pie"}  
}  
2.query:{  
match:{"search\_term": "apple is good"}  
}

1 - is valid since it contains both apple & pie  
2- Not valid since not contains both

---

<div class="post-metadata">

**Author:** ![dadoonet](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/dadoonet/32/137187_2.png) [@dadoonet](https://discuss.elastic.co/u/dadoonet)\
**Post date:** [February 16, 2019, 6:03pm UTC](https://discuss.elastic.co/t/exact-match-search-with-permutation-of-words/165643/12 "2019-02-16T18:03:29Z")

</div>

How elasticsearch can know that `apple` and `pie` are terms you are looking for but `is` and `good` are not? Are you going to provide a list of stopwords?

Do you mean that all the terms in the document must match terms provided by the user?

---

<div class="post-metadata">

**Author:** ![ankur\_singla](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/ankur_singla/32/45612_2.png) [@ankur\_singla](https://discuss.elastic.co/u/ankur_singla)\
**Post date:** [February 16, 2019, 6:24pm UTC](https://discuss.elastic.co/t/exact-match-search-with-permutation-of-words/165643/13 "2019-02-16T18:24:44Z")

</div>

No, I will not provide any list of stopwords.

Yes if all the terms of any document contained in user terms it should return in the response.

e.g.  
**1-"apple pie" - is indexed doc in ES**  
**{"search\_term": "apple pie", "category": "apple product"} - indexed doc**

**2-"banana pie" - is indexed doc in ES**  
**{"search\_term": "banana pie", "category": "banana product"} - indexed doc**

**3-"banana shake" - is indexed doc in ES**  
**{"search\_term": "banana shake", "category": "banana product"} - indexed doc**

**Query-**  
**{**  
**query:{match:{"search\_term": "I like apple banana pie"}}**  
**}**

I only want to return 1st & 2nd docs cause user terms contains all 1st(apple pie) & 2nd(banana pie) docs terms but not 3rd doc since user terms only contain "banana" not "shake".

---

<div class="post-metadata">

**Author:** ![dadoonet](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/dadoonet/32/137187_2.png) [@dadoonet](https://discuss.elastic.co/u/dadoonet)\
**Post date:** [February 16, 2019, 6:43pm UTC](https://discuss.elastic.co/t/exact-match-search-with-permutation-of-words/165643/14 "2019-02-16T18:43:55Z")

</div>

@jpountz any idea?

---

<div class="post-metadata">

**Author:** ![ankur\_singla](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/ankur_singla/32/45612_2.png) [@ankur\_singla](https://discuss.elastic.co/u/ankur_singla)\
**Post date:** [February 17, 2019, 6:40pm UTC](https://discuss.elastic.co/t/exact-match-search-with-permutation-of-words/165643/15 "2019-02-17T18:40:56Z")

</div>

Hi @jpountz

Please help me out on this if you have any idea.

---

<div class="post-metadata">

**Author:** ![dadoonet](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/dadoonet/32/137187_2.png) [@dadoonet](https://discuss.elastic.co/u/dadoonet)\
**Post date:** [February 17, 2019, 8:47pm UTC](https://discuss.elastic.co/t/exact-match-search-with-permutation-of-words/165643/16 "2019-02-17T20:47:05Z")

</div>

Read [this](https://discuss.elastic.co/t/about-the-elasticsearch-category/21) and specifically the "Also be patient" part.

It's fine to answer on your own thread after 2 or 3 days (not including weekends) if you don't have an answer.

---

<div class="post-metadata">

**Author:** ![ankur\_singla](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/ankur_singla/32/45612_2.png) [@ankur\_singla](https://discuss.elastic.co/u/ankur_singla)\
**Post date:** [February 18, 2019, 7:41am UTC](https://discuss.elastic.co/t/exact-match-search-with-permutation-of-words/165643/17 "2019-02-18T07:41:19Z")

</div>

Apologies for being impatience & I will keep this in mind. Thank you for info 😀

---

<div class="post-metadata">

**Author:** ![jpountz](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/jpountz/32/45836_2.png) [@jpountz](https://discuss.elastic.co/u/jpountz)\
**Post date:** [February 19, 2019, 6:31pm UTC](https://discuss.elastic.co/t/exact-match-search-with-permutation-of-words/165643/18 "2019-02-19T18:31:14Z")

</div>

I see, you want the query terms to be a superset of the indexed terms. We support this but it requires some manual work. first you need to index your documents as an array and a separate field must record the number of terms, eg.

```auto
{
  "tokens": ["apple", "pie"],
  "token_count": 2
}

```

Then at search time you can use the `terms_set` query ([https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-terms-set-query.html](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-terms-set-query.html)):

```auto
{
  "query": {
    "terms_set": {
      "tokens": {
        "terms": ["apple", "banana", "pie"],
        "minimum_should_match_field": "token_count"
      }
    }
  }
}

```

Note that tokens must be mapped as a `keyword` field.

---

<div class="post-metadata">

**Author:** ![ankur\_singla](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/ankur_singla/32/45612_2.png) [@ankur\_singla](https://discuss.elastic.co/u/ankur_singla)\
**Post date:** [February 20, 2019, 5:20pm UTC](https://discuss.elastic.co/t/exact-match-search-with-permutation-of-words/165643/19 "2019-02-20T17:20:57Z")

</div>

Thanks a lot, @jpountz. Your reply is a lifesaver 😍

Thanks again.😀

---

<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:** [March 20, 2019, 5:20pm UTC](https://discuss.elastic.co/t/exact-match-search-with-permutation-of-words/165643/20 "2019-03-20T17:20:59Z")

</div>

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