**What is Autocomplete ?**\n\nLet’s take a very common example. Whenever you go to [google](https://hackernoon.com/tagged/google) and start typing, a drop-down appears which lists the suggestions. Those suggestions are related to the query and help the user in completing his query.\n\n!(https://hackernoon.com/hn-images/1*Vq_ETVxcROG7fBtMkiqJuw.png)\n\nSuggestions when typing on Google\n\nAutocomplete as the [wikipedia](https://en.wikipedia.org/wiki/Autocomplete) says\n\n> Autocomplete, or word completion, is a feature in which an application predicts the rest of a word a user is typing\n\nIt is also known as **Search as you type** or **Type Ahead Search**. It helps in navigating or guiding a user by prompting them with likely completions and alternatives to the text as they are typing it. It reduces the amount of character a user needs to type before executing any search actions, thereby enhancing the [search](https://hackernoon.com/tagged/search) experience of users.\n\nAutoCompletion can be implemented by using any database. In this post, we will use [**Elasticsearch**](https://www.elastic.co/products/elasticsearch) to build autocomplete functionality.\n\nElasticsearch is an open source, distributed and JSON based search engine built on top of [Lucene](https://lucene.apache.org/core/).\n\n### **Approaches**\n\nThere can be various approaches to build autocomplete functionality in Elasticsearch. We will discuss the following approaches.\n\n* Prefix Query\n* Edge Ngram\n* Completion Suggester\n\n**Prefix Query**\n\nThis approach involves using a [prefix query](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-prefix-query.html) against a custom field. The value for this field can be stored as a keyword so that multiple terms(words) are stored together as a single term. This can be accomplished by using [keyword tokeniser](https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-keyword-tokenizer.html). This approach has some disadvantages.\n\n* Since the matching is supported only at the beginning of the term, one cannot match the query in the **middle** of the text.\n* This type of query is not optimised for **large dataset** and may result in increased latency.\n* Since this is a query, **duplicate results** won’t be filtered out. One workaround to deal with this approach can be using an aggregation query to group results and then filtering out results. This involves a bit of processing though on the server side.\n\n**Edge Ngrams**\n\nThis approach involves using **different analysers** at index and search time. When indexing the document, a custom analyser with an [edge n-gram](https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-edgengram-tokenizer.html) filter can be applied. At search time, [standard analyser](https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-standard-analyzer.html) can be applied. which prevents the query from being split.\n\nEdge N-gram tokeniser first breaks the text down into words on custom characters (space, special characters, etc..) and then keeps the n-gram from the start of the string only.\n\nThis approach works well for matching query in the middle of the text as well. This approach is generally fast for queries but may result in slower indexing and in large index storage.\n\n**Completion Suggester**\n\nElasticsearch is shipped with an in-house solution called [Completion Suggester](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-suggesters-completion.html). It uses an in-memory data structure called [Finite State Transducer](https://en.wikipedia.org/wiki/Finite-state_transducer)(FST). Elasticsearch stores FST on a per segment basis, which means suggestions scale horizontally as more new nodes are added.\n\nSome of the things to keep in mind when implementing Completion Suggester\n\n* The autosuggest items should have `completion` types as its field type.\n* An input field can have various canonical or alias name for a single term.\n* Weights can be defined with each document to control their ranking.\n* Storing all the terms in lowercase helps in the case-insensitive match.\n* Context suggesters can be enabled to support filtering or boosting by certain criteria.\n\nThis approach is the ideal approach to implement autocomplete functionality, however, it also has certain disadvantages\n\n* Matching always starts at the beginning of the text. So search for `america` in marvels movie dataset will not yield any result. One way to overcome is tokenizing the input text on space and keep all the phrases as canonical names. This way `Captain America: Civil War` will be stored as\n\n!(https://avatars3.githubusercontent.com/u/4302268?s=400&v=4)\n\nHighlighting of the matched words are not supported.\n\n* No sorting mechanism is available. The only way to sort suggestions is via weights. This creates a problem when any custom sorting like alphabetical sort or sort by context is required.\n\n### **Implementation**\n\nLet’s implement the above approaches in Elasticsearch. We will be using Marvels movie data to build our sample index. For easy reference, here is the\n\n* Spider-Man: Homecoming\n* Ant-man and the Wasp\n* Avengers: Infinity War Part 2\n* Captain Marvel\n* Black Panther\n* Avengers: Infinity War\n* Thor: Ragnarok\n* Guardians of the Galaxy Vol 2\n* Doctor Strange\n* Captain America: Civil War\n* Ant-Man\n* Avengers: Age of Ultron\n* Guardians of the Galaxy\n* Captain America: The Winter Soldier\n* Thor: The Dark World\n* Iron Man 3\n* Marvel’s The Avengers\n* Captain America: The First Avenger\n* Thor\n* Iron Man 2\n* The Incredible Hulk\n* Iron Man\n\nWe will be creating an index `movies` with type `marvels.`\n\n!(https://avatars3.githubusercontent.com/u/4302268?s=400&v=4)\n\nIf we see the mapping, we will observe that name is a nested field which contains several field, each analysed in a different way.\n\n* Field`name.keywordstring` is analysed using a Keyword tokenizer, hence it will be used for **Prefix Query** Approach\n* Field `name.edgengram` is analysed using Edge Ngram tokenizer, hence it will be used for **Edge Ngram** Approach.\n* Field `name.completion` is stored as a completion type, hence it will be used for Completion Suggester.\n\nWe will index all our movies by using\n\n!(https://avatars3.githubusercontent.com/u/4302268?s=400&v=4)\n\nLet’s start with Prefix Query approach and try finding movie beginning with `th`.\n\nQuery will be\n\n!(https://avatars3.githubusercontent.com/u/4302268?s=400&v=4)\n\nThis will result in the following movie\n\n* Thor: The Dark World\n* Thor: Ragnarok\n* The Incredible Hulk\n* Thor\n\nThe result is fair, but some movies like _Captain America: The Winter Soldier_, _Guardians of the Galaxy_ are **missed** because prefix query only matches at the beginning of the text and not in the middle.\n\nLets try finding another movie beginning with `am`.\n\n!(https://avatars3.githubusercontent.com/u/4302268?s=400&v=4)\n\nHere we do not get any results, although _Captain America_ satisfy this condition. This confirms the point that Prefix query cannot be used to match in the middle of the text.\n\nLet's run the same search `am` but with Edge Ngram Approach.\n\n!(https://avatars3.githubusercontent.com/u/4302268?s=400&v=4)\n\nHere we get the following result\n\n* Captain America: The First Avenger\n* Captain America: Civil War\n* Captain America: The Winter Soldier\n\nLet’s try finding for Captain America again, but this time with a bigger phrase `captain america the`\n\nUsing Edge N-gram approach, we get the following movies\n\n* Captain America: The Winter Soldier\n* Captain America: The First Avenger\n* Captain America: Civil War\n* Thor: The Dark World\n* Captain Marvel\n* Guardians of the Galaxy\n* The Incredible Hulk\n* Guardians of the Galaxy Vol 2\n* Ant-man and the Wasp\n* Marvel’s The Avengers\n\nIf we observe our phrase, only the first two suggestion makes sense. The reason for so many terms getting matched is the functioning of `match` clause. match includes all the documents which contain `captain OR america OR the`. Since the field is analysed using ngram, more suggestions(if present) will get included as well.\n\nLet’s try using the suggestion query for the same phrase `captain america the` . Suggestion query is written in a slightly different way.\n\n!(https://avatars3.githubusercontent.com/u/4302268?s=400&v=4)\n\nWe get the following movies as result\n\n* Captain America: The First Avenger\n* Captain America: The Winter Soldier\n\nLet’s try the same query, but this time with a typo `captain amrica the`.\n\nThe above `movie-suggest` returns no result because no support for fuzziness is present. We can update the query to include support for fuzziness in the following way\n\n!(https://avatars3.githubusercontent.com/u/4302268?s=400&v=4)\n\nThe above query returns the following results\n\n* Captain America: The First Avenger\n* Captain America: The Winter Soldier\n\n### Conclusion\n\nVarious approaches can be used to implement autocomplete functionality in ElasticSearch. Completion Suggester covers most of the cases which are required in implementing a fully functional and fast autocomplete.