# Edge ngram with phrase matching

**URL:** <https://discuss.elastic.co/t/edge-ngram-with-phrase-matching/57580>\
**Category:** Elasticsearch\
**Created:** [August 9, 2016, 10:12am UTC](https://discuss.elastic.co/t/edge-ngram-with-phrase-matching/57580 "2016-08-09T10:12:05Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![trex](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/trex/32/34230_2.png) [@trex](https://discuss.elastic.co/u/trex)\
**Post date:** [August 9, 2016, 10:12am UTC](https://discuss.elastic.co/t/edge-ngram-with-phrase-matching/57580/1 "2016-08-09T10:12:05Z")

</div>

I need to autocomplete phrases. For example, when I search "dementia in alz", I want to get "dementia in alzheimer's".

For this, I configured Edge NGram tokenizer. I tried both edge\_ngram\_analyzer and standard as the analyzer in the query body. Nevertheless, I can't get results when I'm trying to match a phrase.

What am I doing wrong?g?

My query:  
`{ "query":{ "multi_match":{ "query":"dementia in alz", "type":"phrase", "analyzer":"edge_ngram_analyzer", "fields":["_all"] } } }`

My mappings:

```
...
"type" : {
  "_all" : {
    "analyzer" : "edge_ngram_analyzer",
    "search_analyzer" : "standard"
  },
  "properties" : {
    "field" : {
      "type" : "string",
      "analyzer" : "edge_ngram_analyzer",
      "search_analyzer" : "standard"
    },
...
"settings" : {
  ...
  "analysis" : {
    "filter" : {
      "stem_possessive_filter" : {
        "name" : "possessive_english",
        "type" : "stemmer"
      }
    },
    "analyzer" : {
      "edge_ngram_analyzer" : {
        "filter" : ["lowercase"],
        "tokenizer" : "edge_ngram_tokenizer"
      }
    },
    "tokenizer" : {
      "edge_ngram_tokenizer" : {
        "token_chars" : ["letter", "digit", "whitespace"],
        "min_gram" : "2",
        "type" : "edgeNGram",
        "max_gram" : "25"
      }
    }
  }
  ...

```

Analysis of the "dementia in alzheimer" phrase:

```
{
  "tokens": [
    {
      "end_offset": 2, 
      "token": "de", 
      "type": "word", 
      "start_offset": 0, 
      "position": 0
    }, 
    {
      "end_offset": 3, 
      "token": "dem", 
      "type": "word", 
      "start_offset": 0, 
      "position": 1
    }, 
    {
      "end_offset": 4, 
      "token": "deme", 
      "type": "word", 
      "start_offset": 0, 
      "position": 2
    }, 
    {
      "end_offset": 5, 
      "token": "demen", 
      "type": "word", 
      "start_offset": 0, 
      "position": 3
    }, 
    {
      "end_offset": 6, 
      "token": "dement", 
      "type": "word", 
      "start_offset": 0, 
      "position": 4
    }, 
    {
      "end_offset": 7, 
      "token": "dementi", 
      "type": "word", 
      "start_offset": 0, 
      "position": 5
    }, 
    {
      "end_offset": 8, 
      "token": "dementia", 
      "type": "word", 
      "start_offset": 0, 
      "position": 6
    }, 
    {
      "end_offset": 9, 
      "token": "dementia ", 
      "type": "word", 
      "start_offset": 0, 
      "position": 7
    }, 
    {
      "end_offset": 10, 
      "token": "dementia i", 
      "type": "word", 
      "start_offset": 0, 
      "position": 8
    }, 
    {
      "end_offset": 11, 
      "token": "dementia in", 
      "type": "word", 
      "start_offset": 0, 
      "position": 9
    }, 
    {
      "end_offset": 12, 
      "token": "dementia in ", 
      "type": "word", 
      "start_offset": 0, 
      "position": 10
    }, 
    {
      "end_offset": 13, 
      "token": "dementia in a", 
      "type": "word", 
      "start_offset": 0, 
      "position": 11
    }, 
    {
      "end_offset": 14, 
      "token": "dementia in al", 
      "type": "word", 
      "start_offset": 0, 
      "position": 12
    }, 
    {
      "end_offset": 15, 
      "token": "dementia in alz", 
      "type": "word", 
      "start_offset": 0, 
      "position": 13
    }, 
    {
      "end_offset": 16, 
      "token": "dementia in alzh", 
      "type": "word", 
      "start_offset": 0, 
      "position": 14
    }, 
    {
      "end_offset": 17, 
      "token": "dementia in alzhe", 
      "type": "word", 
      "start_offset": 0, 
      "position": 15
    }, 
    {
      "end_offset": 18, 
      "token": "dementia in alzhei", 
      "type": "word", 
      "start_offset": 0, 
      "position": 16
    }, 
    {
      "end_offset": 19, 
      "token": "dementia in alzheim", 
      "type": "word", 
      "start_offset": 0, 
      "position": 17
    }, 
    {
      "end_offset": 20, 
      "token": "dementia in alzheime", 
      "type": "word", 
      "start_offset": 0, 
      "position": 18
    }, 
    {
      "end_offset": 21, 
      "token": "dementia in alzheimer", 
      "type": "word", 
      "start_offset": 0, 
      "position": 19
    }
  ]
}
```

---

<div class="post-metadata">

**Author:** ![davidbkemp](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/davidbkemp/32/594_2.png) [@davidbkemp](https://discuss.elastic.co/u/davidbkemp)\
**Post date:** [August 9, 2016, 12:41pm UTC](https://discuss.elastic.co/t/edge-ngram-with-phrase-matching/57580/2 "2016-08-09T12:41:44Z")

</div>

Phrase match is for matching a sequence of tokens with consecutive "start offsets". For example: "dementia" at 0, "in" at 1, and "alz" at 2.

If you look at the results of your analysis, edge ngram tokenising has resulted in tokens that all have a start offset of zero. One of those tokens is "dementia in alz", **but it is a single token**.

Try a query analyser consisting of the keyword tokenizer and lowercase token filter, and use a simple match query instead of a phrase match. Then "Dementia in Alz" will hopefully be transformed into a single token "dementia in alz", which in turn will match the corresponding edge ngram.

---

<div class="post-metadata">

**Author:** ![trex](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/trex/32/34230_2.png) [@trex](https://discuss.elastic.co/u/trex)\
**Post date:** [August 9, 2016, 2:22pm UTC](https://discuss.elastic.co/t/edge-ngram-with-phrase-matching/57580/3 "2016-08-09T14:22:48Z")

</div>

@davidbkemp I added the following to the existing mappings:

```
     "analyzer": {
        ...
        "keyword_analyzer": {
          "filter": ["lowercase"],
          "tokenizer": "keyword"
        }
     }

```

And changed query to  
`{'query': {'multi_match': {'query': 'dementia in alz', 'analyzer': 'keyword_analyzer', 'fields': ['_all']}}}`

No results had been returned.

---

<div class="post-metadata">

**Author:** ![nik9000](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/nik9000/32/44947_2.png) [@nik9000](https://discuss.elastic.co/u/nik9000)\
**Post date:** [August 9, 2016, 5:11pm UTC](https://discuss.elastic.co/t/edge-ngram-with-phrase-matching/57580/4 "2016-08-09T17:11:57Z")

</div>

At this point I'd go poke around the `_analyze` API and compare the tokens that the analyzer your query uses vs the one you've put on \_all.

BTW, if you are only querying one field, I'd go with `match` instead of `multi_match`. `multi_match` is a fairly large thing and `match` is much easier to read and debug.

---

<div class="post-metadata">

**Author:** ![davidbkemp](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/davidbkemp/32/594_2.png) [@davidbkemp](https://discuss.elastic.co/u/davidbkemp)\
**Post date:** [August 9, 2016, 10:14pm UTC](https://discuss.elastic.co/t/edge-ngram-with-phrase-matching/57580/5 "2016-08-09T22:14:05Z")

</div>

I just noticed that you are querying the "\_all" field. This probably won't work as it will contain all the fields concatenated together into "one big string"  
[https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-all-field.html](https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-all-field.html)

---

<div class="post-metadata">

**Author:** ![trex](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/trex/32/34230_2.png) [@trex](https://discuss.elastic.co/u/trex)\
**Post date:** [August 10, 2016, 7:29am UTC](https://discuss.elastic.co/t/edge-ngram-with-phrase-matching/57580/6 "2016-08-10T07:29:20Z")

</div>

Guys, thank you very mach for your responses. @davidbkemp you are right in your first response.  
You can see the solution on Stackoverflow

> <https://stackoverflow.com/questions/38848121/edge-ngram-with-phrase-matching>

---

<div class="post-metadata">

**Author:** ![trex](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/trex/32/34230_2.png) [@trex](https://discuss.elastic.co/u/trex)\
**Post date:** [August 11, 2016, 10:38am UTC](https://discuss.elastic.co/t/edge-ngram-with-phrase-matching/57580/7 "2016-08-11T10:38:22Z")

</div>

Guys, finally the correct solution had been found yesterday. Please look at my answer on StackOverflow.

> <https://stackoverflow.com/questions/38848121/edge-ngram-with-phrase-matching/38893908#38893908>

---

<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:** [July 5, 2017, 10:28pm UTC](https://discuss.elastic.co/t/edge-ngram-with-phrase-matching/57580/8 "2017-07-05T22:28:28Z")

</div>


