How to add fuzziness to search as you type field in Elasticsearch?

Viewed 1217

I've been trying to add some fuzziness to my search as you type field type on Elasticsearch, but never got the needed query. Anyone have any idea to implement this?

2 Answers

Fuzzy Query returns documents that contain terms similar to the search term, as measured by a Levenshtein edit distance.

The fuzziness parameter can be specified as:

AUTO -- It generates an edit distance based on the length of the term. For lengths:

0..2 -- must match exactly

3..5 -- one edit allowed Greater than 5 -- two edits allowed

Adding working example with index data and search query.

Index Data:

{
  "title":"product"
}
{
  "title":"prodct"
}

Search Query:

    {
    "query": {
        "fuzzy": {
            "title": {
                "value": "prodc",
                "fuzziness":2,
                "transpositions":true,
                 "boost": 5
            }
        }
    }
}

Search Result:

"hits": [
  {
    "_index": "test",
    "_type": "_doc",
    "_id": "1",
    "_score": 2.0794415,
    "_source": {
      "title": "product"
    }
  },
  {
    "_index": "test",
    "_type": "_doc",
    "_id": "2",
    "_score": 2.0794415,
    "_source": {
      "title": "produt"
    }
  }
]

Refer these blogs to get a detailed explaination on fuzzy query

https://www.elastic.co/blog/found-fuzzy-search

https://qbox.io/blog/elasticsearch-optimization-fuzziness-performance

Update 1: Refer this ES official documentation

The fuzziness , prefix_length , max_expansions , rewrite , and fuzzy_transpositions parameters are supported for the terms that are used to construct term queries, but do not have an effect on the prefix query constructed from the final term.

There are some open issues and discuss links that states that - Fuzziness not work with bool_prefix multi_match (search-as-you-type)

https://github.com/elastic/elasticsearch/issues/56229

https://discuss.elastic.co/t/fuzziness-not-work-with-bool-prefix-multi-match-search-as-you-type/229602/3

I know this question is asked long ago but I think this worked for me.

Since Elasticsearch allows a single field to be declared with multiple data types, my mapping is like below.

PUT products
{
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "fields": {
          "product_type": {
            "type": "search_as_you_type"
          }
        }
      }
    }
  }
}

After adding some data to the index I fetched like this.

GET products/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "multi_match": {
            "query": "prodc",
            "type": "bool_prefix",
            "fields": [
              "title.product_type",
              "title.product_type._2gram",
              "title.product_type._3gram"
            ]
          }
        },
        {
          "multi_match": {
            "query": "prodc",
            "fuzziness": 2
          }
        }
      ]
    }
  }
}

Related