Elasticsearch PHP - Exact Word Matches Before Partial Matches
Get the solution ↓↓↓So I'm trying to sort my search results to show the exact matches before all the partial matches. What I mean by this is if I have the documents with names:
Set 4/102
Set 44/102
Set 94/102
I'm searching on the term 4/102 and it returns all documents. This is fine, however, I want the Set 4/102 to show up first but it seemingly sorts them randomly. Is there a way to use script sorting or something like that to have the exact term match to show up first?
These are my mappings and settings:
$settingsParams = [
'index' => 'products',
'body' => [
'settings' => [
'analysis' => [
'analyzer' => [
'substring_analyzer' => [
'tokenizer' => 'substring_tokenizer',
'filter' => [
'lowercase'
]
],
'fullword_analyzer' => [
'tokenizer' => 'whitespace',
'filter' => [
'lowercase'
]
],
],
'tokenizer' => [
'substring_tokenizer' => [
'type' => 'nGram',
'min_gram' => 3,
'max_gram' => 12,
'token_chars' => [
'letter',
'digit',
'symbol',
'custom'
],
'custom_token_chars' => '/'
]
]
],
'max_ngram_diff' => 20
]
]
];
$mappingParams = [
'index' => 'products',
'body' => [
'_source' => [
'enabled' => true
],
'properties' => [
'name' => [
'type' => 'text',
'fields' => [
'keyword' => [
'type' => 'keyword'
]
],
'analyzer' => 'substring_analyzer',
'search_analyzer' => 'fullword_analyzer'
],
'min_price' => [
'type' => 'double'
],
'saleprice' => [
'type' => 'double'
],
'list_price' => [
'type' => 'double'
],
'root_category_rank' => [
'type' => 'integer'
],
'interest_level' => [
'type' => 'integer'
],
'root_categoryid' => [
'type' => 'integer'
]
]
]
];
Answer
Solution:
Adding a working example
Index Mapping:
{
"settings": {
"analysis": {
"analyzer": {
"substring_analyzer": {
"tokenizer": "substring_tokenizer"
},
"fullword_analyzer": {
"tokenizer": "whitespace"
}
},
"tokenizer": {
"substring_tokenizer": {
"type": "ngram",
"min_gram": 3,
"max_gram": 12,
"token_chars": [
"letter",
"digit",
"custom",
"symbol"
],
"custom_token_chars": "/"
}
}
},
"max_ngram_diff": 50
},
"mappings": {
"properties": {
"name": {
"type": "text",
"analyzer": "substring_analyzer",
"search_analyzer": "fullword_analyzer"
}
}
}
}
Search Query:
{
"query": {
"match": {
"name": "4/102"
}
}
}
Search Result:
The document"name": "4/102"
is having a higher score as compared to other documents
"hits": [
{
"_index": "66232066",
"_type": "_doc",
"_id": "1",
"_score": 0.15275992,
"_source": {
"name": "4/102" // note this
}
},
{
"_index": "66232066",
"_type": "_doc",
"_id": "2",
"_score": 0.12562492,
"_source": {
"name": "44/102"
}
},
{
"_index": "66232066",
"_type": "_doc",
"_id": "3",
"_score": 0.12562492,
"_source": {
"name": "94/102"
}
}
]
Share solution ↓
Additional Information:
Link To Answer People are also looking for solutions of the problem: warning: a non-numeric value encountered in
Didn't find the answer?
Our community is visited by hundreds of web development professionals every day. Ask your question and get a quick answer for free.
Similar questions
Find the answer in similar questions on our website.
Write quick answer
Do you know the answer to this question? Write a quick response to it. With your help, we will make our community stronger.