Hey Elasticsearch,
a year ago I wrote a topic here What is the best way to query first and last name? to help me out with searching users in my database. At that time, I partially resolved the problem.
Now, I found this topic How i search firstname + lastname in elasticsearch written by @arunkvinam where he did not find the solution.
I believe there are some experts in Elasticsearch forum, so I hope they will be able to answer few my questions.
I dag entire internet and there is no single example on how to search users.
I have one field "Search" where you can enter anything and it should find user based on the string you have written. However, the more chars you write, the more exact the result should be and:
EXAMPLE 1:
- "An" should return
-
Anna Abc (starts with
An
, high score) - George Annado (again, high score)
- John van Annabis (high score, because third word starts with
An
) - Adriana Xyz (
an
is placed inside the word, low score) - Joanna Def (same as above)
- Michael Joan (same as above)
-
Anna Abc (starts with
What ElasticSearch does in this case it returns properly 1 and 2 only because the word starts with An
, however 3, 4, 5 and 6 are not included in the output.
EXAMPLE 2:
- "Anna" should return
- Anna Abc (matches whole word, highest score)
- George Annado (starts with
Anna
, high score) - John van Annabis (high score, because third word starts with
Anna
) - Joanna Def (matches part of the word, low score)
What ElasticSearch does in this case it returns properly 1 and 2 only because the word matches Anna
, however 3 and 4 is not included in the response.
In perfect wor(l)d it should hit highest score (Anna Abc) when full phrase matched the word, high score (Anna Abc) when beginning of the word is matching the word and low score (Joanna Def) when phrase is inside the word.
Here is my configuration:
indexes:
app:
settings:
index:
analysis:
analyzer:
search_analyzer:
type: custom
tokenizer: tokenizer
filter: [lowercase, asciifolding]
filter:
asciifolding:
type: asciifolding
preserve_original: true
tokenizer:
tokenizer:
type: keyword
....
user:
type: object
properties:
firstName:
type: string
analyzer: search_analyzer
lastName:
type: string
analyzer: search_analyzer
and the query is defined as follows:
$boolQuery = new Query\BoolQuery();
$boolQuery
->addMust((new Query\MultiMatch())
->setFields(['firstName', 'lastName'])
->setType(Query\MultiMatch::TYPE_PHRASE_PREFIX)
->setOperator(Query\MultiMatch::OPERATOR_OR)
->setQuery('Anna')
);
$query = new Query();
$query->setQuery($boolQuery);
$result = $this->finder->find($query);
Would be super cool to get the results as closed as possible using Elasticsearch because there is no any example, how to make it perfectly when it comes to searching users.
Currently I switched back to MySQL LIKE query because it does the job pretty okay (not perfect) but I would like to have this done using Elasticsearch.
I hope I will get some advises.