# Query returning false results when term exceeds ngram length

**URL:** https://discuss.elastic.co/t/query-returning-false-results-when-term-exceeds-ngram-length/112392
**Category:** Elasticsearch
**Created:** [December 19, 2017, 9:27am UTC](https://discuss.elastic.co/t/query-returning-false-results-when-term-exceeds-ngram-length/112392 "2017-12-19T09:27:04Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![Paul\_Davies](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/paul_davies/32/25787_2.png) [@Paul\_Davies](https://discuss.elastic.co/u/Paul_Davies)
#### Post date: [December 19, 2017, 9:27am UTC](https://discuss.elastic.co/t/query-returning-false-results-when-term-exceeds-ngram-length/112392/1 "2017-12-19T09:27:04Z")

</div>

The requirement is to search partial phrases in a block of text. Most of the words will be standard length. I want to keep the max\_gram value down to 10. But there may be the occasional id/code with more characters than that, and these show up if I type in a query where the first 10 characters match, but then the rest don't.

For example, here is the mapping:

```
PUT my_index
{
  "settings": {
    "analysis": {
      "analyzer": {
        "autocomplete": {
          "tokenizer": "autocomplete",
          "filter": [
            "lowercase"
          ]
        }
      },
      "tokenizer": {
        "autocomplete": {
          "type": "edge_ngram",
          "min_gram": 1,
          "max_gram": 10,
          "token_chars": [
            "letter"
          ]
        }
      }
    }
  },
  "mappings": {
    "doc": {
      "properties": {
        "title": {
          "type": "text",
          "analyzer": "autocomplete"
        }
      }
    }
  }
}

```

and document:

```
POST my_index/doc/1
{
  "title": "Quick fox with id of ABCDEFGHIJKLMNOP" 
}

```

If I run the query:

```
POST my_index/doc/_search
{
  "query": {
    "match_phrase": {
      "title": {
        "query": "fox wi"
      }
    }
  }
}

```

It returns the document as expected. However, if I run this:

```
POST my_index/doc/_search
{
  "query": {
    "match_phrase": {
      "title": {
        "query": "ABCDEFGHIJxxx"
      }
    }
  }
}

```

It also returns the document, when it shouldn't. It will do this if the x's are after the 10th character, but not before it. How can I avoid this?

I am using version 5.

---

<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: [December 19, 2017, 10:37am UTC](https://discuss.elastic.co/t/query-returning-false-results-when-term-exceeds-ngram-length/112392/2 "2017-12-19T10:37:43Z")

</div>

You can use a `simple` analyzer at search time instead the default ngram one that you set.

A full example here: [https://www.elastic.co/guide/en/elasticsearch/reference/6.1/search-analyzer.html](https://www.elastic.co/guide/en/elasticsearch/reference/6.1/search-analyzer.html)

---

<div class="post-metadata">

### Author: ![Paul\_Davies](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/paul_davies/32/25787_2.png) [@Paul\_Davies](https://discuss.elastic.co/u/Paul_Davies)
#### Post date: [December 19, 2017, 1:28pm UTC](https://discuss.elastic.co/t/query-returning-false-results-when-term-exceeds-ngram-length/112392/3 "2017-12-19T13:28:20Z")

</div>

So you're saying the mappings part is like this?

```
"mappings": {
      "doc": {
        "properties": {
          "title": {
            "type": "text",
            "analyzer": "autocomplete"
          }
        }
      }
    }

```

Unfortunately this doesn't work with match\_phrase.

This query:

```
POST my_index/doc/_search
{
  "query": {
    "match_phrase": {
      "title": {
        "query": "quick fox"
      }
    }
  }
}

```

Now return no results

---

<div class="post-metadata">

### Author: ![Paul\_Davies](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/paul_davies/32/25787_2.png) [@Paul\_Davies](https://discuss.elastic.co/u/Paul_Davies)
#### Post date: [December 19, 2017, 2:17pm UTC](https://discuss.elastic.co/t/query-returning-false-results-when-term-exceeds-ngram-length/112392/4 "2017-12-19T14:17:35Z")

</div>

I seem to have found a solution to this. The solution was to change the default search\_analyser, but not in the way suggested by @dadoonet.

Here is the mapping:

```
{
  "settings": {
    "analysis": {
      "analyzer": {
        "autocomplete": {
          "tokenizer": "autocomplete",
          "filter": [
            "lowercase"
          ]
        },
        "autocomplete_search": {
          "tokenizer": "autocomplete_search",
          "filter": [
          	"lowercase"
          ]
        }
      },
      "tokenizer": {
        "autocomplete": {
          "type": "edge_ngram",
          "min_gram": 1,
          "max_gram": 10,
          "token_chars": [
            "letter", "digit"
          ]
        },
        "autocomplete_search": {
          "type": "edge_ngram",
          "min_gram": 1,
          "max_gram": 100,
          "token_chars": [
            "letter", "digit"
          ]
        }
      }
    }
  },
  "mappings": {
    "doc": {
      "properties": {
        "title": {
          "type": "text",
          "analyzer": "autocomplete",
          "search_analyzer": "autocomplete_search"
        }
      }
    }
  }
}

```

I don't 100% understand what is going on here, but the search\_analyser defaults to be the same as the analyser.

**Please correct me if I'm wrong on any of this:**

The analyser is what is applied to the the record being indexed at indexing time, and the search\_analyser field is applied to the search term at query time.

When applied to the search term, the term is broken down into ngrams with a maximum length of 10.  
Comparing **ABCDEFGHIJxxx** to **ABCDEFGHIJKLMNOP** comes out as a positive match as it is only comparing the first ten characters.

I din't want to increase max\_gram for the indexing analyser too much because this can slow down both indexing and searching.

So I have increased max\_gram for the search term, and it is now trying yo match up to the first 100 characters (should be sufficient) to the 10 character ngrams in the index.

This means that typing the exact code **ABCDEFGHIJKLMNOP** doesn't come up with a match, but this can be fixed by indexing another field with the standard analyser and doing a multimatch on both fields.

---

<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: [December 19, 2017, 5:47pm UTC](https://discuss.elastic.co/t/query-returning-false-results-when-term-exceeds-ngram-length/112392/5 "2017-12-19T17:47:12Z")

</div>

`autocomplete` and `autocomplete_search` are doing the same thing.  
So IMO, this:

```auto
        "title": {
          "type": "text",
          "analyzer": "autocomplete",
          "search_analyzer": "autocomplete_search"
        }

```

is the same as:

```auto
        "title": {
          "type": "text",
          "analyzer": "autocomplete"
        }

```

---

<div class="post-metadata">

### Author: ![Paul\_Davies](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/paul_davies/32/25787_2.png) [@Paul\_Davies](https://discuss.elastic.co/u/Paul_Davies)
#### Post date: [December 19, 2017, 6:54pm UTC](https://discuss.elastic.co/t/query-returning-false-results-when-term-exceeds-ngram-length/112392/6 "2017-12-19T18:54:12Z")

</div>

They're not the same: the autocomplete analyzer uses the autocomplete tokenizer, and the utocomplete analyzer\_search uses the autocomplete\_search tokenizer (may have been an idea to use different names for the analyzer and tokenizer. Autocomplete and autocomplete\_search tokenizers have max\_gram set to 10 and 100 respectively, which is how I got it to work.

---

<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: [January 16, 2018, 6:54pm UTC](https://discuss.elastic.co/t/query-returning-false-results-when-term-exceeds-ngram-length/112392/7 "2018-01-16T18:54:13Z")

</div>

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