I recently upgraded from Elasticsearch 1.4 to 5.4 and I'm struggling to migrate my autocomplete queries efficiently. The problem is that I want to have a completion suggester where the output is different from the input.
The documents I store have a field for categories which is basically an array of strings with their URIs (because they form a tree). The last part of the URI, I call it label, is the input in the completion suggester, but as a response I would like to retrieve the full URI.
So let's say I have two documents:
{
"name" : "Lord of The Rings",
"categories" : ["Books/Genre/Fantasy", "Books/Language/English"]
}
and
{
"name" : "Game of Thrones",
"categories" : ["Series/Genre/Fantasy", "Series/Host/HBO"]
}
My input is "Fant" and I want to get as a response the URIs for the "Series/Genre/Fantasy" and "Books/Genre/Fantasy" categories.
Previously with ES 1.4, I was able to create a completion suggester with a different output for a given input, so I indexed my suggesters like this:
{
"suggest" : {
"input": [ "Fantasy"],
"output": "Series/Genre/Fantasy"
}
}
and
{
"suggest" : {
"input": [ "Fantasy"],
"output": "Books/Genre/Fantasy"
}
}
But in ES 5.4, the output property doesn't exist anymore for completion suggesters so all I get in the response is the input
property of my suggest field, which is the label "Fantasy", but I want the URI.
Right now, my workaround is to look for the categories
field of each document returned in the _source
property of the response, and filter on the categories that have a label starting with the input "Fant". It is very inefficient since I need to map every category of every returned document into its label to check with the input.
Isn't there a more efficient way to do that with ES suggesters? What am I missing?
Elasticsearch's completion suggester have been changed from 5.0.
The support for specifying output when indexing suggestion entries has been removed. Now suggestion result entry’s text is always the un-analyzed value of the suggestion’s input (same as not specifying output while indexing suggestions in pre-5.0 indices).
So you need to add output
as a sibling field of suggest
key in the body.
Here's how it should look like:
Mapping:
{
"mappings": {
"<type>" : {
"properties" : {
"suggest" : {
"type" : "completion"
},
"output" : {
"type": "keyword"
}
}
}
}
}
Don't forget to replace <type>
with your index type.
Indexing:
/<index_name>/<type_name>
{
"suggest" : {
"input": ["Fantasy"],
"weight" : 1
},
"output": "Series/Genre/Fantasy"
}
Here, the field name output
can be replaced by anything, it's just meta-data of your document.
Query:
/<index_name>/_search
{
"suggest": {
"show-suggest" : {
"prefix" : "Fant",
"completion" : {
"field" : "suggest"
}
}
}
}
I hope this helps.