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"
}

 

三、 代碼實現

public Page<B2bMallSkuDto> 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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章