esstarter12345
esstarter12345

Reputation: 21

ElasticSearch autocomplete

I have got four documents with a field named "fullname".

Documents:

I would like to make an autocompleter for this field. Some examples:

Search: "Abi" Result: "Abigail Harrison", "Abigale Hardison", "Abilene Havington"

Search: "Abig" Result: "Abigail Harrison", "Abigale Hardison"

Search: "Abigail Har" Result: "Abigail Harrison", "Abigale Hardison"

Search: "Abilene Hav" Result: "Abilene Havington", "Abilene-Havington"

Search: "Har" Result: "Abigail Harrison", "Abigale Hardison"

I do not want something like this: (!)

Search: "iga" Result: "Abigail Harrison", "Abigale Hardison"

Whitespaces and hyphens should be ignored and I'd like to have all generated tokens lowercase, so the search query should not be case-sensitive.

My ES settings are the following.

{
"mappings": {
    "person": {
        "properties": {
            "fullname": {
                "index": "analyzed",
                "index_analyzer": "autocomplete",
                "search_analyzer": "standard",
                "type": "string"
            }
        }
    }
},
"settings": {
    "index": {
        "analysis": {
            "analyzer": {
                "autocomplete": {
                    "filter": [
                        "lowercase",
                        "edgengram"
                    ],
                    "tokenizer": "whitespace"
                }
            },
            "filter": {
                "edgengram": {
                    "max_gram": 50,
                    "min_gram": 3,
                    "type": "edgeNGram"
                }
            }
        }
    }
}

}

Upvotes: 1

Views: 610

Answers (1)

dark_shadow
dark_shadow

Reputation: 3573

While indexing you should use a standard tokenizer along with lowercase, asciifolding, suggestion_shingle, edgengram and while searching use a keyword analyzer.

Try using something like this:

"index":{
"analysis": {
    "analyzer": {
        "autocomplete": {
            "tokenizer": "standard",
            "filter": [
                "lowercase",
                "asciifolding",
                "suggestions_shingle",
                "edgengram"
            ]
        }
    },
    "filter": {
        "suggestions_shingle": {
            "type": "shingle",
            "min_shingle_size": 2,
            "max_shingle_size": 5
        },
        "edgengram": {
            "type": "edgeNGram",
            "min_gram": 2,
            "max_gram": 30,
            "side": "front"
        }
    }
}
}

"mappings": {
    "person": {
        "properties": {
            "fullname": {
                "index": "analyzed",
                "index_analyzer": "autocomplete",
                "search_analyzer": "keyword",
                "type": "string"
            }
        }
    }
}

And then try searching using a match query. It should solve your problem.

Thanks

Upvotes: 1

Related Questions