In my program, the user can "disable" fuzzy searching on the front-end. This changes the back-end request to the following:
$query['query']['bool']['must'][] = [
'bool' => [
'should' => [
['match_phrase' => ['name' => $param]],
['match_phrase' => ['description' => $param]],
],
'minimum_should_match' => 1,
],
];
The $param
is the search query. The document I am looking to hit is Evo-Singularity
.
The following is my hits on this:
evo
=> works
evo-
=> works
evo-sing
=> no results
singularity
=> works
With that in mind, I’ve tried changing to a wildcard
approach:
$param = '*'.$param.'*';
//No Fuzzy Search - Do a literal match
$query['query']['bool']['must'][] = [
'wildcard' => [
'name' => $param
],
'wildcard' => [
'description' => $param
],
];
evo
=> works
evo-
=> no results
evo-sing
=> no results
singularity
=> no results
Then I went to the console to try see if I could find it:
This works:
{
"query": {
"match": {
"name": "evo-singularity"
}
}
}
None of these wildcard searches work:
{
"query": {
"wildcard": {
"name": {
"value": "*evo\-singularity*",
"boost": 1.0,
"rewrite": "constant_score"
}
}
}
}
or
{
"query": {
"wildcard": {
"name": {
"value": "*evo*singularity*",
"boost": 1.0,
"rewrite": "constant_score"
}
}
}
}
But this does work:
{
"query": {
"wildcard": {
"name": {
"value": "*singularity*",
"boost": 1.0,
"rewrite": "constant_score"
}
}
}
}
Here is the actual document in elasticsearch. I’ve removed all unnecessary information:
"_source": {
"type": "Trap Card",
"description": "Target 1 "Evoltile" monster and 1 "Evolsaur" monster in your Graveyard; Special Summon 1 "Evolzar" Xyz Monster from your Extra Deck, and if you do, attach those monsters to it as Xyz Materials.",
"name": "Evo-Singularity",
},
At this stage, I’m out of ideas. Documents that have space hyphen space seem to work without issue:
vanquish soul - kaiser
But documents that have no space around the hyphens have issue:
evo-singularity
My analyzer settings:
{
"card_database": {
"settings": {
"index": {
"provided_name": "card_database",
"number_of_replicas": "1",
"max_result_window": "15000",
"uuid": "Jfgh8F_FQQO21qSkQDngFw",
"number_of_shards": "1",
"analysis": {
"filter": {
"my_stopwords_filter": {
"stopwords": [
"a",
"an",
"the"
],
"type": "stop"
}
},
"analyzer": {
"my_analyzer": {
"filter": [
"lowercase",
"my_stopwords_filter"
],
"tokenizer": "standard"
}
}
},
"creation_date": "1676906459467",
"version": {
"created": "8060199"
},
"routing": {
"allocation": {
"include": {
"_tier_preference": "data_content"
}
}
},
"blocks": {
"read_only_allow_delete": "false"
}
}
}
}
}
Here is a link to my mappings:
2
Answers
If the field is indexed as a keyword try to change the query to a term query
TLDR;
It seems like you don’t want to be using a
match_phrase
type of query but amatch_phrase_prefix
query.As in the doc:
The
extact phrases
makes me think this is not what you want in the case ofevo-sing
.Solution
You may switch to a match_phrase_prefix query instead:
To reproduce
I use elasticsearch
8.6.2
Set up:
Notes
Although you have provided an analyser in your question.
You are not using it on the
name
field, so I used the standard analyzer.