In the highlighted query, only the digit is highlighted and not the special characters, this is because of the standard analyzer. Since, you have not defined any analyzer, for your title field, so the standard analyzer is the default analyzer which is used if none is specified.
GET/_analyze
{
"analyzer" : "standard",
"text" : "100% guarantee"
}
Following tokens are generated:
{
"tokens": [
{
"token": "100",
"start_offset": 0,
"end_offset": 3,
"type": "<NUM>",
"position": 0
},
{
"token": "guarantee",
"start_offset": 5,
"end_offset": 14,
"type": "<ALPHANUM>",
"position": 1
}
]
}
You can see that Elasticsearch's standard analyzer just strips the "%" character. The analyzer is applied at index time so your text never makes it into the index as you want it.
Adding a working example with index data, mapping, search query, and search result
Index Mapping:
{
"settings": {
"analysis": {
"analyzer": {
"my_analyzer": {
"type": "custom",
"filter": [
"lowercase"
],
"tokenizer": "whitespace"
}
}
}
},
"mappings": {
"properties": {
"title": {
"type": "text",
"analyzer": "my_analyzer"
}
}
}
}
Analyze API:
GET/_analyze
{
"analyzer" : "my_analyzer",
"text" : "100% guarantee"
}
Following tokens are generated:
{
"tokens": [
{
"token": "100%",
"start_offset": 0,
"end_offset": 4,
"type": "word",
"position": 0
},
{
"token": "guarantee",
"start_offset": 5,
"end_offset": 14,
"type": "word",
"position": 1
}
]
}
Index Data:
{
"title": "100% guarantee"
}
{
"title": "100 guarantee"
}
Search Query:
{
"query": {
"query_string": {
"default_field": "title",
"query": "100%",
"allow_leading_wildcard": false
}
},
"size": 5,
"highlight": {
"fields": {
"title": {
"type": "plain",
"fragment_size": 20,
"pre_tags": "<span class='bold'>",
"post_tags": "</span>",
"number_of_fragments": 1
}
}
}
}
Search Result:
"hits": [
{
"_index": "64608747",
"_type": "_doc",
"_id": "1",
"_score": 0.6931471,
"_source": {
"title": "100% guarantee"
},
"highlight": {
"title": [
"<span class='bold'>100%</span> guarantee"
]
}
}
]