elasticsearch7.17.3实现对中文排序

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分词器,具体大家可以自己多多尝试尝试

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值