I have a problem with a relevant search. Results of following request are very strange:
Candidate.search('martin', fields: [:first_name, :last_name],
match: :word_start, misspellings: false).map(&:name)
["Kautzer Martina",
"Funk Martin",
"Jaskolski Martin",
"Gutmann Martine",
"Wiegand Martina",
"Schueller Martin",
"Dooley Martin",
"Stiedemann Martine",
"Bartell Martina",
"Gerlach Martine",
"Green Martina",
"Lang Martine",
"Legros Martine",
"Ernser Martina",
"Boehm Martina",
"Green Martine",
"Nolan Martin",
"Schmidt Martin",
"Hoppe Martin",
"Macejkovic Martine",
"Emard Martine"]
Why Martina is going earlier than Martin?
Searckick config:
searchkick language: %w(German English), word_start: [:first_name, :last_name]
Searchkick 1.4 fixes this issue. There's even a test case dedicated to this question :)
When using word_start
, what searchkick actually does is to tokenize the chosen fields (:first_name
and :last_name
) using the searchkick_word_start_index
analyzer. That analyzer is a custom one which uses the following edgeNGram token filter:
searchkick_edge_ngram: {
type: "edgeNGram",
min_gram: 1,
max_gram: 50
},
So, when Kautzer Martina
gets indexed, the following tokens are actually produced and indexed:
:first_name
: m
, ma
, mar
, mart
, marti
, martin
, martina
:last_name
: k
, ka
, kau
, kaut
, kautz
, kautze
, kautzer
Similarly, for Funk Martin
:
:first_name
: m
, ma
, mar
, mart
, marti
, martin
:last_name
: f
, fu
, fun
, funk
As you can see, when searching for martin
, both will match because both contain the token martin
and they will be sorted by descending score (default). If you want to order the results differently, you can use sorting and call your search
with
order: [{last_name: :asc},{first_name: :asc}]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With