elasticsearch版本:7.17.3
目标:实现对类型为text字段的中文排序
目录
一、用icu分词器对中文排序
注意:
- 如果字段中既有中文又有英文,会先把中文按字母顺序排序,再排英文
1、安装icu分词器
执行下面命令后,重启es即可
sudo bin/elasticsearch-plugin install analysis-icu
有下面图中内容代表安装成功
2、创建索引时增加sort排序内容
下面内容是创建了一个名为es_test的索引内容,其中包含名为fileName字段,以ik分词器分词,排序内容以icu分词器排序
PUT /es_test
{
"mappings":{
"properties":{
"fileName":{
"type":"text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_smart",
"fields": {
"sort": {
"type": "icu_collation_keyword",
"index": false,
"language": "zh",
"country": "pinyin"
}
}
}
}
}
}
3、es命令方式排序
GET es_test/_search
{
"sort": [
{
"fileName.sort": {
"order": "desc"
}
}
]
}
4、java调用的方式排序
这里只写client.search中的内容,要想看如何完整的调用,可以看我此系列的其他文章
SortOptions sortOption = SortOptions.of(_1 -> _1.field(_2 -> _2.field("fileName.sort").order(SortOrder.Desc)));
SearchResponse<Map> search = client.search(_1 -> _1
.index(indexName)
//es默认返回10000条数据,加上此条配置才能返回全部条数
.trackTotalHits(_2 -> _2.enabled(true))
//查询参数
.query(queryBuilder.build()._toQuery())
.from(pageBegin)
.size(dto.getPageSize())
.sort(sortOption)
, Map.class);
二、用pinyin分词器实现中文排序
注意
- pinyin对数字的排序可能不会太理想
- 由于fielddata会在内存中加载并存储每个文档的字段数据,以便在排序和聚合等操作中使用,此方式占用内存要更大,尤其是启用了fielddata选项时
- 可以将"fileName.pinyin"字段的数据类型更改为"keyword"类型,就可以直接对字段进行聚合和排序,而无需使用fielddata(需要注意keyword类型和text类型的区别,根据自己需要确定)
1、安装pinyin分词器
执行以下命令,根据自己的版本对应的修改
bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-pinyin/releases/download/v7.17.3/elasticsearch-analysis-pinyin-7.17.3.zip
2、创建索引时增加sort相关内容
下面内容是创建了一个名为es_test的索引内容,其中包含名为fileName字段,以ik分词器分词,相当于还创建了一个名为pinyin的字段,用pinyin分词器支持排序功能
PUT /es_test
{
"settings": {
"analysis": {
"analyzer": {
"ik_max_word": {
"tokenizer": "ik_max_word"
},
"ik_smart": {
"tokenizer": "ik_smart"
},
"pinyin_analyzer": {
"tokenizer": "my_pinyin"
}
},
"tokenizer": {
"my_pinyin": {
"type": "pinyin",
"keep_separate_first_letter": false,
"keep_full_pinyin": true,
"keep_original": true,
"limit_first_letter_length": 16,
"lowercase": true,
"remove_duplicated_term": true,
"trim_whitespace": true
}
}
}
},
"mappings":{
"properties":{
"fileName":{
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_smart",
"fields": {
"pinyin": {
"type": "text",
"analyzer": "pinyin_analyzer",
"fielddata":true
}
}
}
}
}
}
3、es命令方式排序
POST es_test/_search
{
"sort": [
{
"fileName.pinyin": {
"order": "asc"
}
}
]
}
4、java调用的方式排序
这里只写client.search中的内容,要想看如何完整的调用,可以看我此系列的其他文章
SortOptions sortOption = SortOptions.of(_1 -> _1.field(_2 -> _2.field("fileName.pinyin").order(SortOrder.Desc)));
SearchResponse<Map> search = client.search(_1 -> _1
.index(indexName)
//es默认返回10000条数据,加上此条配置才能返回全部条数
.trackTotalHits(_2 -> _2.enabled(true))
//查询参数
.query(queryBuilder.build()._toQuery())
.from(pageBegin)
.size(dto.getPageSize())
.sort(sortOption)
, Map.class);
尾声
还有其他的支持中文排序的实现方式,比如用smartcn分词器或者jieba分词器,具体大家可以自己多多尝试尝试