Search code examples
elasticsearch

Is an nGram fuzzy search possible?


I'm trying to get an nGram filter to work with a fuzzy search, but it won't. Specifically, I'm trying to get "rugh" to match on "rough".

I don't know whether it's just not possible, or it is possible but I've defined the mapping wrong, or the mapping is fine but my search isn't defined correctly.

Mapping:

{
    settings = new
        {
            index = new
            {
                number_of_shards = 1,
                number_of_replicas = 1,

                analysis = new
                {
                    filter = new
                    {
                        edge_ngram_filter = new
                        {
                            type = "nGram",
                            min_gram = 3,
                            max_gram = 8
                        }
                    }, // filter

                    analyzer = new
                    {
                        analyzer_ngram = new
                        {
                            type = "custom",
                            tokenizer = "standard",
                            filter = new string[]
                            {
                                "lowercase",
                                "edge_ngram_filter"
                            }
                        }
                    }  // analyzer

                } // analysis

            } // index
        },  //  settings

    mappings = new
    {
        j_cv = new
        {
            properties = new
            {
                Text = new
                {
                    type = "text",
                    include_in_all = false,
                    analyzer = "analyzer_ngram",
                    search_analyzer = "standard"
                }
            }
        }   //  j_cv
    }   //  mappings
}

Document:

{
   Id = Guid.NewGuid(),
   Name = "Jimmy Riddle",
   Keyword = new List<string>(new string[] { "Hunting", "High", "Hotel", "California" }),
   Text = "Rough Justice was a program on BBC some years ago. It was quite interesting. Will this match?"
}

Search:

{
    query = new
    {
        query_string = new
        {
            fields = new string[] { "Text" },
            fuzziness = "3",
            query = "rugh"
        }
    }
}

Incidentally, "ugh" does match which is what you'd expect.


Solution

  • The same analyzer should usually be applied at index and search time, so search_analyzer=standard is wrong, it should be working if you remove it. https://www.elastic.co/guide/en/elasticsearch/reference/current/search-analyzer.html

    Edit: You forgot the fuzzy operator "~" in your query, if you add it to "rugh" it will work!