Elasticsearch7.* + SpringBoot2.*根据中文和拼音分页去重搜索

目的:根据商品名称按中文和拼音分页搜索,并且按商品名去重。这里以Elasticsearch7.4为例。

一、插件安装

1、安装ik中文分词器

下载地址:https://github.com/medcl/elasticsearch-analysis-ik/releases/tag/v7.4.0

  1. 进入es安装目录 elasticsearch/plugins/
  2. 新建文件夹:analysis-ik
  3. 将下载的压缩包解压到elasticsearch/plugins/analysis-ik目录下
  4. 重启es

2、安装pinyin分词器

下载地址:https://github.com/medcl/elasticsearch-analysis-pinyin/releases/tag/v7.4.0

  1. 进入es安装目录 elasticsearch/plugins/
  2. 新建文件夹:pinyin
  3. 将下载的压缩包解压到elasticsearch/plugins/pinyin目录下
  4. 重启es

二、索引结构

创建索引:

PUT /sku_index2
{
  "mappings":{
    "properties": {
      "id": {
        "type": "keyword"
      },
      "skuId": {
        "type": "long"
      },
      "skuName": {
        "type": "text",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
          },
          "ik": {
            "type": "text",
            "analyzer": "ik_max_word"
          },
          "pinyin": {
            "type": "text",
            "analyzer": "pinyin"
          }
        }
      }
    }
  }
}

 一个string字段可以映射为text用于全文搜索的字段,也可以映射为keyword用于排序或聚合的字段。大多数数据类型通过fields参数支持多字段。这里设置两个分词器:中文和拼音,关键字类型是为去重操作作准备。

新增文档数据...(省略)

测试分词器:

GET /sku_index2/_analyze
{
  "text": "我今天超级无敌开心",
  "analyzer": "ik_max_word"
}

GET /b2b_mall_sku_index2/_analyze
{
  "text": "chaojikaixin",
  "analyzer": "pinyin"
}

Elasticsearch7.* + SpringBoot2.*根据中文和拼音分页去重搜索_第1张图片 Elasticsearch7.* + SpringBoot2.*根据中文和拼音分页去重搜索_第2张图片

三、 代码实现

public Page search1(String query, Integer hits, Integer start) {
        if (Objects.isNull(hits)) {
            hits = 10;
        }
        if (Objects.isNull(start)) {
            start = 0;
        }
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        //搜索条件 //此处中文匹配得分稍高于拼音,默认boost为1
        //此处注意,当must和should共用时,should条件会失效,需要调整方法调用
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery()
                .should(QueryBuilders.matchQuery("skuName.ik", query).boost(1.2f))
                .should(QueryBuilders.matchQuery("skuName.pinyin", query));
        queryBuilder.withQuery(boolQueryBuilder);
        //分页 开始位置,每页条数
        queryBuilder.withPageable(PageRequest.of(start, hits));
        //折叠去重(按照skuName去重)
        queryBuilder.withCollapseField("skuName.keyword");
        return b2bMallRepository.search(queryBuilder.build());
    }
  1. must :所有的语句都 必须(must) 匹配,与 AND 等价。 
  2. must_not :所有的语句都 不能(must not) 匹配,与 NOT 等价。 
  3. should :至少有一个语句要匹配,与 OR 等价。

Collapse性能高于top_hits + 聚合统计agg,Collapse字段必须是keyword类型

四、问题

withCollapseField()方法折叠去重后,分页后结果的totalCount数量指叠前数量。

参考文档:

  1. 官方文档
  2. https://blog.csdn.net/laoyang360/article/details/79905676

你可能感兴趣的:(Elasticsearch)