# Autocomplete best match is not first in results

**URL:** <https://discuss.elastic.co/t/autocomplete-best-match-is-not-first-in-results/279186>\
**Category:** Elasticsearch\
**Created:** [July 20, 2021, 3:51pm UTC](https://discuss.elastic.co/t/autocomplete-best-match-is-not-first-in-results/279186 "2021-07-20T15:51:42Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![net](https://avatars.discourse-cdn.com/v4/letter/n/9de0a6/32.png) [@net](https://discuss.elastic.co/u/net)\
**Post date:** [July 20, 2021, 3:51pm UTC](https://discuss.elastic.co/t/autocomplete-best-match-is-not-first-in-results/279186/1 "2021-07-20T15:51:42Z")

</div>

When I search for "charles sta" the first result in the list is "U.S. Dept. of State, Office of Logistics Management, Charleston" and the second result is "Charles Stark Draper Laboratory, Inc. (CSDL)"

The second result is a better match. I'm wondering why it's showing the first result as the best match rather than the second? And how can I update what I'm doing to have the second result be the best match.

Here is my mapping:

companies.json mapping:

```auto
{
    "settings": {
        "index": {
            "max_result_window": 1000000,
            "number_of_shards": 4
        },
        "analysis": {
            "normalizer": {
                "case_insensitive": {
                    "filter": "lowercase"
                }
            },
            "analyzer": {
                "autocomplete": {
                    "tokenizer": "autocomplete",
                    "filter": [
                        "lowercase",
                        "asciifolding"
                    ]
                },
                "autocomplete_search": {
                    "tokenizer": "lowercase",
                    "filter": [
                        "asciifolding"
                    ]
                }
            },
            "tokenizer": {
                "autocomplete": {
                    "type": "edge_ngram",
                    "min_gram": 2,
                    "max_gram": 10,
                    "token_chars": [
                        "letter"
                    ]
                }
            }
        }
    },
    "aliases": {
        "companies-loading": {}
    },
    "mappings": {
        "properties": {
            "esIndex": {
                "type": "keyword"
            },
            "name": {
                "type": "text",
                "analyzer": "autocomplete",
                "search_analyzer": "autocomplete_search",
                "fields": {
                    "keyword": {
                        "type": "keyword",
                        "ignore_above": 256
                    }
                }
            },
            "name_suggest": {
                "type": "completion",
                "contexts": [
                    {
                      "name": "index_name",
                      "type": "category"
                    }
                ]
            }
        }
    }
}

```

agency.json mapping

```auto
{
    "settings": {
        "index": {
            "max_result_window": 1000000,
            "number_of_shards": 4
        },
        "analysis": {
            "normalizer": {
                "case_insensitive": {
                    "filter": "lowercase"
                }
            },
            "analyzer": {
                "autocomplete": {
                    "tokenizer": "autocomplete",
                    "filter": [
                        "lowercase",
                        "asciifolding"
                    ]
                },
                "autocomplete_search": {
                    "tokenizer": "lowercase",
                    "filter": [
                        "asciifolding"
                    ]
                }
            },
            "tokenizer": {
                "autocomplete": {
                    "type": "edge_ngram",
                    "min_gram": 2,
                    "max_gram": 10,
                    "token_chars": [
                        "letter"
                    ]
                }
            }
        }
    },
    "aliases": {
        "agency-loading": {}
    },
    "mappings": {
        "properties": {
            "esIndex": {
                "type": "keyword"
            },
            "uid": {
                "type": "integer"
            },
            "name": {
                "type": "text",
                "analyzer": "autocomplete",
                "search_analyzer": "autocomplete_search",
                "fields": {
                    "keyword": {
                        "type": "keyword",
                        "ignore_above": 256
                    }
                }
            },
            "name_suggest": {
                "type": "completion",
                "contexts": [
                    {
                      "name": "index_name",
                      "type": "category"
                    }
                ]
            }
        }
    }
}

```

Search query I'm using:

```auto
// url: https://localhost:9200/companies,agency/_search
// elasticsearch 7.9
{
  "_source": [
    "name",
    "type",
    "uid"
  ],
  "size": 2,
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "name": {
              "query": "charles sta"
            }
          }
        }
      ]
    }
  },
  "suggest": {
    "nameSuggestions": {
      "prefix": "charles sta",
      "completion": {
        "field": "name_suggest",
        "skip_duplicates": true,
        "contexts": {
          "index_name": [
            {
              "context": "agency",
              "boost": 2
            },
            {
              "context": "companies",
              "boost": 2
            }
          ]
        },
        "size": 2
      }
    }
  }
}

```

And the results that come back:

```auto
{
    "took": 3,
    "timed_out": false,
    "_shards": {
        "total": 8,
        "successful": 8,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 171,
            "relation": "eq"
        },
        "max_score": 8.716487,
        "hits": [
            {
                "_index": "agency-1626509281",
                "_type": "_doc",
                "_id": "O7OCs3oByp01hMO1rWYM",
                "_score": 8.716487,
                "_source": {
                    "uid": 43638,
                    "name": "U.S. Dept. of State, Office of Logistics Management, Charleston",
                    "type": "agency"
                }
            },
            {
                "_index": "companies-1626509290",
                "_type": "_doc",
                "_id": "vICCs3oBQl5LKuna7PeW",
                "_score": 7.525751,
                "_source": {
                    "name": "Charles Stark Draper Laboratory, Inc. (CSDL)",
                    "type": "companies"
                }
            }
        ]
    },
    "suggest": {
        "nameSuggestions": [
            {
                "text": "charles sta",
                "offset": 0,
                "length": 11,
                "options": []
            }
        ]
    }
}

```

---

<div class="post-metadata">

**Author:** ![spinscale](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/spinscale/32/25011_2.png) [@spinscale](https://discuss.elastic.co/u/spinscale)\
**Post date:** [July 21, 2021, 2:27pm UTC](https://discuss.elastic.co/t/autocomplete-best-match-is-not-first-in-results/279186/2 "2021-07-21T14:27:39Z")

</div>

You just hit the miracles of full text search. The way you configured your index/analysis chain by using ngrams means, it is harder to score on full terms as you lose that information.

How about indexing your data as text without any configuration and create a `bool` query that contains `should` clause with a `match` query against that field, so that hits that match full terms in your query are scored higher?

Even though it is somewhat dated, Elasticsearch - The definitive Guide is still a really valuable resource in order to take a step back and understand how mapping and full text search works. See [Dealing with Human Language | Elasticsearch: The Definitive Guide [2.x] | Elastic](https://www.elastic.co/guide/en/elasticsearch/guide/current/languages.html) as a start (I highly recommend chapters before and after as well).

Also, as a side note,you may want to take a look at the [search as you type field type](https://www.elastic.co/guide/en/elasticsearch/reference/7.13/search-as-you-type.html)

hope this helps as a start!

---

<div class="post-metadata">

**Author:** ![net](https://avatars.discourse-cdn.com/v4/letter/n/9de0a6/32.png) [@net](https://discuss.elastic.co/u/net)\
**Post date:** [July 21, 2021, 2:51pm UTC](https://discuss.elastic.co/t/autocomplete-best-match-is-not-first-in-results/279186/3 "2021-07-21T14:51:51Z")

</div>

Thanks for info. I'll check that out. My overall goal is to create a good autocomplete. What I'm doing is from this blog article: [Autocompletion for Public Transportation | mimacom](https://blog.mimacom.com/autocomplete-elasticsearch-part4/)

It has it's strengths but then its weak in the following scenario I showed. Would it be possible to improve it in the scenario I showed by combined what you said with what they did? What I mean is, would it make sense to index another field without any configuration. And then add that to the query chain to increase the score?

Thanks for the book. I've read through that before and it was helpful. I have a pretty large application that has searching and filtering kind of like an amazon website. I'm falling short on building a good autocomplete. It's mostly good but falls short in the example I provided.

Thanks for the mention on search\_as\_you\_type field. I'm going to try that out to see how it compares to what I have so far. I'm currently using the other autocomplete option, context suggestor, and the reason was so I could boost certain contexts.

---

<div class="post-metadata">

**Author:** ![spinscale](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/spinscale/32/25011_2.png) [@spinscale](https://discuss.elastic.co/u/spinscale)\
**Post date:** [July 22, 2021, 1:35pm UTC](https://discuss.elastic.co/t/autocomplete-best-match-is-not-first-in-results/279186/4 "2021-07-22T13:35:02Z")

</div>

Yes, I think influencing scoring when someone typed a word that is a full hit makes sense.. however test with outliers like very common terms in your dataset to be sure it works as expected!

---

<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:** [August 19, 2021, 1:35pm UTC](https://discuss.elastic.co/t/autocomplete-best-match-is-not-first-in-results/279186/5 "2021-08-19T13:35:21Z")

</div>

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