您可以使用自定义分析器在索引时执行相同的操作,该分析器利用
pattern_replace
字符过滤器。与为每个查询运行脚本排序相比,将其放在索引中执行更加高效。
它的工作方式与您的解决方案相同,即如果我们检测到一个数字,我们会在值前面添加一个波浪符号
~
,否则我们不做任何操作,但我们是在索引时执行,并将结果值索引到
name.sort
字段中。
PUT /tests
{
"settings": {
"analysis": {
"char_filter": {
"pre_num": {
"type": "pattern_replace",
"pattern": "(\\d)",
"replacement": "~$1"
}
},
"analyzer": {
"number_tagger": {
"type": "custom",
"tokenizer": "keyword",
"filter": [],
"char_filter": [
"pre_num"
]
}
}
}
},
"mappings": {
"test": {
"properties": {
"name": {
"type": "string",
"fields": {
"sort": {
"type": "string",
"analyzer": "number_tagger",
"search_analyzer": "standard"
}
}
}
}
}
}
}
然后您可以对数据进行索引。
POST /tests/test/_bulk
{"index": {}}
{"name": "ZBA ABC"}
{"index": {}}
{"name": "ABC SDK"}
{"index": {}}
{"name": "123 RIU"}
{"index": {}}
{"name": "12B BTE"}
{"index": {}}
{"name": "11J TRE"}
{"index": {}}
{"name": "BCA 642"}
那么你的查询可以简单地写成这样:
POST /tests/_search
{
"sort": {
"name.sort": "asc"
}
}
你会得到以下的响应:
{
"hits": {
"hits": [
{
"_source": {
"name": "ABC SDK"
}
},
{
"_source": {
"name": "BCA 642"
}
},
{
"_source": {
"name": "ZBA ABC"
}
},
{
"_source": {
"name": "11J TRE"
}
},
{
"_source": {
"name": "12B BTE"
}
},
{
"_source": {
"name": "123 RIU"
}
}
]
}
}