elasticsearch实现字符串排序

对于text类型字段,ES默认分词且不会建立正排索引。即使设置"fielddata": true建立正排索引后,对该字段的排序依然有问题:ES不会以整个字段文本排序,而是选择分词后的一个字段进行排序。

对于ES5.x可以设置需要排序的字段为keyword类型,该类型默认不分词且"doc_values":true即默认建立正排索引。

对于需要分词的字段,想实现字符串排序可以将该字段建立两次索引,一个索引设置为text类型用于分词,一个索引设置为keyword类型用于排序。示例如下:

1、建立两次索引

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
PUT /testindex
{
"mappings": {
"testtype":{
"properties": {
"title":{
"type": "text",
"fields": {
"raw":{
"type": "keyword"
}
}
}
}
}
}
}

2、添加数据

1
2
3
4
PUT /testindex/testtype/1
{
"title":"hello world"
}

3、字符串排序

1
2
3
4
5
6
7
8
9
10
11
12
13
GET /testindex/testtype/_search
{
"query": {
"match_all": {}
},
"sort": [
{
"title.raw": {
"order": "asc"
}
}
]
}

4、排序结果

返回结果中,可见ES是以该字段的整个字符串排序,而不是已分词后的一个字段排序。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
{
"hits": {
"total": 1,
"max_score": null,
"hits": [
{
"_index": "testindex",
"_type": "testtype",
"_id": "1",
"_score": null,
"_source": {
"title": "hello world"
},
"sort": [
"hello world"
]
}
]
}
}