Which is the right way to perform an autocomplete?
https://github.com/ankane/searchkick#instant-search--autocomplete
OR
https://github.com/ankane/searchkick/blob/2e6c82a16a542d250922dfb345631b3ba428cd77/test/inheritance_test.rb#L43
For indexing, shouldn't it be autocomplete: [:name] instead of word_start: [:name]?
The readme has the latest instructions. Those tests are for a legacy option.
@ankane I found that autocomplete: true performs the way I would like but word_start does not.
For me if I search for a Product for number "pm07" then I only want that product returned, I don't want "pm01" or "pm03" returned. I was only able to get this to work by using autocomplete:true but I can't figure out why.
If we look at what's created for word_start we find:
Mapping
"product_number" : {
"type" : "keyword",
"fields" : {
"analyzed" : {
"type" : "text"
},
"word_start" : {
"type" : "text",
"analyzer" : "searchkick_word_start_index"
}
},
"ignore_above" : 256
},
Analyzer
searchkick_word_start_index: {
type: "custom",
tokenizer: "standard",
filter: ["lowercase", "asciifolding", "searchkick_edge_ngram"]
},
searchkick_edge_ngram filter
searchkick_edge_ngram: {
type: "edgeNGram",
min_gram: 1,
max_gram: 50
},
If we look at what's created for autocomplete we find:
Mapping
"product_number" : {
"type" : "keyword",
"fields" : {
"analyzed" : {
"type" : "text"
},
"autocomplete" : {
"type" : "text",
"analyzer" : "searchkick_autocomplete_index"
}
},
"ignore_above" : 256
}
Analyzer
"searchkick_autocomplete_index" : {
"filter" : ["lowercase","asciifolding"],
"type" : "custom",
"tokenizer" : "searchkick_autocomplete_ngram"
},
Tokenizer
tokenizer: {
searchkick_autocomplete_ngram: {
type: "edgeNGram",
min_gram: 1,
max_gram: 50
}
}
So I think both word_start and autcomplete use lowercase, asciifolding and edgeNGram.
The difference I think comes in the search query and the use of autocomplete: true. So with word_start we can simply use:
Product.search "pm07"
whereas with autocomplete we have:
Product.search "pm07", autocomplete: true
which I think then uses the following code:
if options[:autocomplete]
payload = {
multi_match: {
fields: fields,
query: term,
analyzer: "searchkick_autocomplete_search"
}
}
searchkick_autocomplete_search: {
type: "custom",
tokenizer: "keyword",
filter: ["lowercase", "asciifolding"]
},
At this point in time I can't figure out what payload code is called/used for word_start and how it differs to that used by autocomplete.
My guess is you need to use misspellings: false. Also, to help with debugging queries and mappings, you can use the recently added:
Product.search("something", debug: true)
Most helpful comment
My guess is you need to use
misspellings: false. Also, to help with debugging queries and mappings, you can use the recently added: