I have a Elasticsearch setup which will allow user to search indexes as wild cards.
array:3 [
"index" => "users"
"type" => "user"
"body" => array:4 [
"from" => 0
"size" => 25
"sort" => array:1 [
1 => array:1 [
"order" => "asc"
]
]
"query" => array:1 [
"bool" => array:1 [
"should" => array:1 [
0 => array:1 [
0 => array:1 [
"wildcard" => array:1 [
"full_name" => "john doe"
]
]
]
]
]
]
]
]
when I pass this array to search function, it is returning an empty array. But there is a document related to "John Doe" and when I run "full_name" => "john"
search is returning the document.
I feel that the problem is with the space.
{
"users": {
"user": {
"properties": {
"address": {
"type": "string"
},
"full_name": {
"type": "string"
},
"industry_name": {
"type": "string"
}
}
}
} }
Assuming field full_name
is analyzed by elasticsearch.
The problem in your case is fact that wildcard query doesn't analyze search string
Matches documents that have fields matching a wildcard expression (not analyzed).
In you case it means, that elasticsearch stored john
and doe
tokens in inverted index, but wildcard query is searching for john doe
token, and it fails.
What you can do about this:
full_name
filed is not analyzed anymore. Note: you will have to search for John Doe
to get match, because value wasn't analyzed so john doe
won't match.You can improve first solution, just by leaving full_name
analyzed, but with custom analyzer(wildcard, lowercase). It will allow you to search for text john doe
or John Doe
.
{
"settings" : {
"index" : {
"analysis" : {
"analyzer" : {
"lowercase_analyzer" : {
"tokenizer" : "keyword",
"filter" : [
"lowercase"
],
"type" : "custom"
}
}
}
}
},
"mappings" : {
"user" : {
"properties" : {
"id" : {
"type" : "integer"
},
"fullName" : {
"analyzer" : "lowercase_analyzer",
"type" : "string"
}
}
}
}
}
You can take advantage of multi field, and search against raw field.
"full_name.raw" => "John Doe"
Hope it will help you handle your use case.
UPDATE
Here you can find more information how to control index mapping.
I think standard tokenizer will be applied by default.
In that case, it will consider the text john doe as phrase.
So try phrase search
"full_name" => "\"john doe\""
If you want to consider spaces you could do something like:
{
"match" : {
"full_name" : {
"query" : "john doe",
"operator" : "and",
"zero_terms_query": "all"
}
}
}
check this: https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-match-query.html