国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

這篇具有很好參考價(jià)值的文章主要介紹了ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

導(dǎo)航:

【黑馬Java筆記+踩坑匯總】JavaSE+JavaWeb+SSM+SpringBoot+瑞吉外賣(mài)+SpringCloud/SpringCloudAlibaba+黑馬旅游+谷粒商城

?黑馬旅游源碼:?

GitHub:

GitHub - vincewm/hotel: 黑馬旅游項(xiàng)目

Gitee:

hotel: 黑馬旅游項(xiàng)目

目錄

1.數(shù)據(jù)聚合

1.1.聚合的種類

1.2.DSL實(shí)現(xiàn)聚合

1.2.1.Bucket聚合語(yǔ)法

1.2.2.聚合結(jié)果排序

1.2.3.通過(guò)query標(biāo)簽限定聚合范圍

1.2.4.度量聚合語(yǔ)法,stats

1.2.5.小結(jié),聚合三要素

1.3.RestAPI實(shí)現(xiàn)聚合

1.3.1.API語(yǔ)法

1.3.2.黑馬旅游業(yè)務(wù)需求,標(biāo)簽隨著搜索結(jié)果變化

1.3.3.業(yè)務(wù)實(shí)現(xiàn)

2.自動(dòng)補(bǔ)全

2.1.pinyin拼音分詞器的介紹和安裝

2.2.自定義分詞器,ik+拼音過(guò)濾

2.2.1 實(shí)現(xiàn)方法?

2.2.2 索引分詞器和搜索分詞器問(wèn)題

2.3.自動(dòng)補(bǔ)全查詢,conmpetion suggester

2.4.實(shí)現(xiàn)酒店搜索框自動(dòng)補(bǔ)全

2.4.1.創(chuàng)建新索引庫(kù),使用自定義分詞器

2.4.2.HotelDoc實(shí)體類添加suggestion字段

2.4.3.重新導(dǎo)入MySQL數(shù)據(jù)到es索引庫(kù)

2.4.4 測(cè)試補(bǔ)全,suggest搜索"rj"結(jié)果“如家”的文檔

2.4.5.自動(dòng)補(bǔ)全查詢的JavaAPI,SuggestBuilder()

2.4.6.實(shí)現(xiàn)旅游項(xiàng)目搜索框自動(dòng)補(bǔ)全

3.mysql與es數(shù)據(jù)同步

3.1.思路分析

3.1.1.方案一:同步調(diào)用

3.1.2.方案二:異步通知

3.1.3.方案三:canal監(jiān)聽(tīng)mysql的binlog

3.1.4.三種方案優(yōu)缺點(diǎn)總結(jié)

3.2.MQ實(shí)現(xiàn)數(shù)據(jù)同步

3.2.1.思路

3.2.2.導(dǎo)入hotel-admin后臺(tái)管理端、修改pom和yml

3.2.3.聲明交換機(jī)、隊(duì)列

3.2.4.后臺(tái)端發(fā)送MQ消息

3.2.5.用戶端接收MQ消息

3.2.6 測(cè)試

3.2.7.vue插件實(shí)現(xiàn)快速拷貝數(shù)據(jù)到表單

4.集群

4.0.概述?

4.1.搭建ES集群

4.1.0.Docker Compose介紹

4.1.1.創(chuàng)建es集群

4.1.2.集群狀態(tài)監(jiān)控,安裝cerebro

4.1.3.創(chuàng)建索引庫(kù)

4.1.4.查看分片效果

4.2.集群腦裂問(wèn)題

4.2.1.集群職責(zé)劃分,四種節(jié)點(diǎn)類型

4.2.2.腦裂問(wèn)題

4.2.3.小結(jié),四種節(jié)點(diǎn)類型

4.3.集群分布式存儲(chǔ)

4.3.1.文檔存儲(chǔ)到分片測(cè)試

4.3.2.分片存儲(chǔ)原理

4.4.集群分布式查詢,協(xié)調(diào)節(jié)點(diǎn)的分散和聚集

4.5.集群故障轉(zhuǎn)移


1.數(shù)據(jù)聚合

聚合(aggregations)可以讓我們極其方便的實(shí)現(xiàn)對(duì)數(shù)據(jù)的統(tǒng)計(jì)、分析、運(yùn)算。例如:

  • 什么品牌的手機(jī)最受歡迎?
  • 這些手機(jī)的平均價(jià)格、最高價(jià)格、最低價(jià)格?
  • 這些手機(jī)每月的銷(xiāo)售情況如何?

實(shí)現(xiàn)這些統(tǒng)計(jì)功能的比數(shù)據(jù)庫(kù)的sql要方便的多,而且查詢速度非??欤梢詫?shí)現(xiàn)近實(shí)時(shí)搜索效果。

1.1.聚合的種類

聚合常見(jiàn)的有三類:

  • 桶(Bucket)聚合:用來(lái)對(duì)文檔做分組

    • TermAggregation:按照文檔字段值分組,例如按照品牌值分組、按照國(guó)家分組
    • Date Histogram:按照日期階梯分組,例如一周為一組,或者一月為一組
  • 度量(Metric)聚合:用以計(jì)算一些值,比如:最大值、最小值、平均值等

    • Avg:求平均值
    • Max:求最大值
    • Min:求最小值
    • Stats:同時(shí)求max、min、avg、sum等
  • 管道(pipeline)聚合:其它聚合的結(jié)果為基礎(chǔ)做聚合

注意:參加聚合的字段必須是不能分詞,例如是keyword、日期、數(shù)值、布爾類型

1.2.DSL實(shí)現(xiàn)聚合

現(xiàn)在,我們要統(tǒng)計(jì)所有數(shù)據(jù)中的酒店品牌有幾種,其實(shí)就是按照品牌對(duì)數(shù)據(jù)分組。此時(shí)可以根據(jù)酒店品牌的名稱做聚合,也就是Bucket聚合。

1.2.1.Bucket聚合語(yǔ)法

語(yǔ)法如下:

GET /hotel/_search
{
  "size": 0,  // 設(shè)置size為0,結(jié)果中不包含文檔,只包含聚合結(jié)果。如果設(shè)為20,就是既展示20個(gè)brand查詢的"hits",又展示聚合"aggregations"
  "aggs": { // 定義聚合
    "聚合名": { //給聚合起個(gè)名字,例如brandAgg。查詢結(jié)果里聚合名會(huì)嵌套在"aggregations"里
      "terms": { // 聚合的類型,按照品牌值聚合,所以選擇term
        "field": "字段名", // 參與聚合的字段,例如brand
        "size": 20 // 希望獲取的聚合結(jié)果數(shù)量
? ? ? ? "order": {
? ? ? ? ? "_count": "asc"????????//按升序排序,默認(rèn)是降序
? ? ? ? }
      }
    }
  }
}

1.2.2.聚合結(jié)果排序

默認(rèn)情況下,Bucket聚合會(huì)統(tǒng)計(jì)Bucket內(nèi)的文檔數(shù)量,記為_(kāi)count,并且按照_count降序排序。

我們可以指定order屬性,自定義聚合的排序方式:

GET /hotel/_search
{
  "size": 0, 
  "aggs": {
    "brandAgg": {
      "terms": {
        "field": "brand",
        "order": {
          "_count": "asc" // 按照_count升序排列
        },
        "size": 20????????
      }
    }
  }
}

?結(jié)果如圖:

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

1.2.3.通過(guò)query標(biāo)簽限定聚合范圍

“query” 標(biāo)簽和“aggs”標(biāo)簽是并列的,“query” 標(biāo)簽不為空就是限定了聚合范圍。

默認(rèn)情況下,Bucket聚合是對(duì)索引庫(kù)的所有文檔做聚合,但真實(shí)場(chǎng)景下,用戶會(huì)輸入搜索條件,因此聚合必須是對(duì)搜索結(jié)果聚合。那么聚合必須添加限定條件。

我們可以限定要聚合的文檔范圍,只要添加query條件即可。

?需求:只對(duì)200元以下的文檔聚合

GET /hotel/_search
{
  "query": {
    "range": {
      "price": {
        "lte": 200 // 只對(duì)200元以下的文檔聚合
      }
    }
  }, 
  "size": 0, 
  "aggs": {
    "brandAgg": {
      "terms": {
        "field": "brand",
        "size": 20
      }
    }
  }
}

這次,聚合得到的品牌明顯變少了:

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

1.2.4.度量聚合語(yǔ)法,stats

上節(jié)課,我們對(duì)酒店按照品牌分組,形成了一個(gè)個(gè)桶。

需求:現(xiàn)在我們需要對(duì)桶內(nèi)的酒店做運(yùn)算,獲取每個(gè)品牌的用戶評(píng)分的min、max、avg等值。

這就要用到Metric聚合了,例如stat聚合:就可以獲取min、max、avg等結(jié)果。

語(yǔ)法如下:

GET /hotel/_search
{
  "size": 0, 
  "aggs": {
    "brandAgg": { 
      "terms": { 
        "field": "字段名", 
        "size": 20
      },
      "aggs": { // 是brands聚合的子聚合,也就是分組后對(duì)每組分別計(jì)算
        "聚合名如score_stats": { // 聚合名稱
          "stats": { // 聚合類型,這里stats可以計(jì)算min、max、avg等。stats是statistics統(tǒng)計(jì)縮寫(xiě)
            "field": "score" // 聚合字段,這里是score
          }
        }
      }
    }
  }
}

這次的score_stats聚合是在brandAgg的聚合內(nèi)部嵌套的子聚合。因?yàn)槲覀冃枰诿總€(gè)桶分別計(jì)算。

我們還可以給聚合結(jié)果做個(gè)排序,例如按照每個(gè)桶的酒店平均分做排序:

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

1.2.5.小結(jié),聚合三要素

aggs代表聚合,與query同級(jí),此時(shí)query的作用是?

  • 限定聚合的的文檔范圍

聚合必須的三要素:

  • 聚合名稱
  • 聚合類型
  • 聚合字段

聚合可配置屬性有:

  • size:指定聚合結(jié)果數(shù)量
  • order:指定聚合結(jié)果排序方式
  • field:指定聚合字段

1.3.RestAPI實(shí)現(xiàn)聚合

1.3.1.API語(yǔ)法

聚合條件與query條件同級(jí)別,因此需要使用request.source()來(lái)指定聚合條件。

聚合條件的語(yǔ)法:

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

注意:request.source().aggregation(),聚合不是負(fù)數(shù),因?yàn)殡m然DSL是"aggs",但它不是數(shù)組,所以不是request.source().aggregations()

聚合結(jié)果:

聚合的結(jié)果也與查詢結(jié)果不同,API也比較特殊。不過(guò)同樣是JSON逐層解析:

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

注意:response.getAggregations().get("brandAgg")的返回結(jié)果要是Terms,注意包別導(dǎo)錯(cuò)了,提示的第一個(gè)不是es的包。

    @Test
    public void aggregation()throws IOException{
        SearchRequest request = new SearchRequest("hotel");
        request.source().size(0).aggregation(AggregationBuilders.terms("brandAgg").field("brand").size(20));
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        Terms brandTerms =response.getAggregations().get("brandAgg");
        List<? extends Terms.Bucket> buckets = brandTerms.getBuckets();
        for(Terms.Bucket bucket:buckets){
            System.out.println(bucket.getKeyAsString()+":"+bucket.getDocCount());
        }
    }

1.3.2.黑馬旅游業(yè)務(wù)需求,標(biāo)簽隨著搜索結(jié)果變化

需求:搜索頁(yè)面的品牌、城市等信息不應(yīng)該是在頁(yè)面寫(xiě)死,而是通過(guò)聚合索引庫(kù)中的酒店數(shù)據(jù)得來(lái)的:

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

分析:

目前,頁(yè)面的城市列表、星級(jí)列表、品牌列表都是寫(xiě)死的,并不會(huì)隨著搜索結(jié)果的變化而變化。但是用戶搜索條件改變時(shí),搜索結(jié)果會(huì)跟著變化。

例如:用戶搜索“東方明珠”,那搜索的酒店肯定是在上海東方明珠附近,因此,城市只能是上海,此時(shí)城市列表中就不應(yīng)該顯示北京、深圳、杭州這些信息了。

也就是說(shuō),搜索結(jié)果中包含哪些城市,頁(yè)面就應(yīng)該列出哪些城市;搜索結(jié)果中包含哪些品牌,頁(yè)面就應(yīng)該列出哪些品牌。

如何得知搜索結(jié)果中包含哪些品牌?如何得知搜索結(jié)果中包含哪些城市?

使用聚合功能,利用Bucket聚合,對(duì)搜索結(jié)果中的文檔基于品牌分組、基于城市分組,就能得知包含哪些品牌、哪些城市了。

因?yàn)槭菍?duì)搜索結(jié)果聚合,因此聚合是限定范圍的聚合,也就是說(shuō)聚合的限定條件跟搜索文檔的條件一致。

查看瀏覽器可以發(fā)現(xiàn),前端其實(shí)已經(jīng)發(fā)出了這樣的一個(gè)請(qǐng)求:

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

請(qǐng)求參數(shù)與搜索文檔的參數(shù)完全一致

返回值類型就是頁(yè)面要展示的最終結(jié)果:

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

結(jié)果是一個(gè)Map結(jié)構(gòu):

  • key是字符串,城市、星級(jí)、品牌、價(jià)格
  • value是集合,例如多個(gè)城市的名稱

1.3.3.業(yè)務(wù)實(shí)現(xiàn)

cn.itcast.hotel.web包的HotelController中添加一個(gè)方法,遵循下面的要求:

  • 請(qǐng)求方式:POST
  • 請(qǐng)求路徑:/hotel/filters
  • 請(qǐng)求參數(shù):RequestParams,與搜索文檔的參數(shù)一致
  • 返回值類型:Map<String, List<String>>

代碼:

    @PostMapping("filters")
    public Map<String, List<String>> getFilters(@RequestBody RequestParams params){
        return hotelService.getFilters(params);
    }

這里調(diào)用了IHotelService中的getFilters方法,尚未實(shí)現(xiàn)。

cn.itcast.hotel.service.IHotelService中定義新方法:

Map<String, List<String>> filters(RequestParams params);

cn.itcast.hotel.service.impl.HotelServiceImpl中實(shí)現(xiàn)該方法:

@Override
public Map<String, List<String>> filters(RequestParams params) {
    try {
        // 1.準(zhǔn)備Request
        SearchRequest request = new SearchRequest("hotel");
        // 2.準(zhǔn)備DSL
        // 2.1.query查詢城市、品牌等基本信息
        buildBasicQuery(params, request);
        // 2.2.設(shè)置size
        request.source().size(0);
        // 2.3.聚合,根據(jù)
        buildAggregation(request);
        // 3.發(fā)出請(qǐng)求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        // 4.解析結(jié)果
        Map<String, List<String>> result = new HashMap<>();
        Aggregations aggregations = response.getAggregations();
        // 4.1.根據(jù)品牌名稱,獲取品牌結(jié)果
        List<String> brandList = getAggByName(aggregations, "brandAgg");
        result.put("brand", brandList);
        // 4.2.根據(jù)品牌名稱,獲取品牌結(jié)果
        List<String> cityList = getAggByName(aggregations, "cityAgg");
        result.put("city", cityList);
        // 4.3.根據(jù)品牌名稱,獲取品牌結(jié)果
        List<String> starList = getAggByName(aggregations, "starAgg");
        result.put("starName", starList);

        return result;
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

//三個(gè)聚合,分別聚合品牌、城市、星級(jí)
private void buildAggregation(SearchRequest request) {
    request.source().aggregation(AggregationBuilders
                                 .terms("brandAgg")
                                 .field("brand")
                                 .size(100)
                                );
    request.source().aggregation(AggregationBuilders
                                 .terms("cityAgg")
                                 .field("city")
                                 .size(100)
                                );
    request.source().aggregation(AggregationBuilders
                                 .terms("starAgg")
                                 .field("starName")
                                 .size(100)
                                );
}

private List<String> getAggByName(Aggregations aggregations, String aggName) {
    // 4.1.根據(jù)聚合名稱獲取聚合結(jié)果
    Terms brandTerms = aggregations.get(aggName);
    // 4.2.獲取buckets
    List<? extends Terms.Bucket> buckets = brandTerms.getBuckets();
    // 4.3.遍歷
    List<String> brandList = new ArrayList<>();
    for (Terms.Bucket bucket : buckets) {
        // 4.4.獲取key
        String key = bucket.getKeyAsString();
        brandList.add(key);
    }
    return brandList;
}

測(cè)試:?

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

2.自動(dòng)補(bǔ)全

當(dāng)用戶在搜索框輸入字符時(shí),我們應(yīng)該提示出與該字符有關(guān)的搜索項(xiàng),如圖:

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

這種根據(jù)用戶輸入的字母,提示完整詞條的功能,就是自動(dòng)補(bǔ)全了。

因?yàn)樾枰鶕?jù)拼音字母來(lái)推斷,因此要用到拼音分詞功能。

2.1.pinyin拼音分詞器的介紹和安裝

要實(shí)現(xiàn)根據(jù)字母做補(bǔ)全,就必須對(duì)文檔按照拼音分詞。在GitHub上恰好有elasticsearch的拼音分詞插件。地址:

https://github.com/medcl/elasticsearch-analysis-pinyin

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

課前資料中也提供了拼音分詞器的安裝包:

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

安裝方式與IK分詞器一樣,分三步:

? ①解壓

? ②上傳到虛擬機(jī)中,elasticsearch的plugin目錄

/var/lib/docker/volumes/es-plugins/_data

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

? ③重啟elasticsearch

docker restart es

? ④測(cè)試

詳細(xì)安裝步驟可以參考IK分詞器的安裝過(guò)程。

測(cè)試用法如下:

POST /_analyze
{
  "text": "如家酒店還不錯(cuò)",
  "analyzer": "pinyin"
}

結(jié)果:

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

2.2.自定義分詞器,ik+拼音過(guò)濾

自定義分詞器適合在創(chuàng)建索引庫(kù)時(shí)使用,不能在搜索時(shí)候用?

2.2.1 實(shí)現(xiàn)方法?

默認(rèn)的拼音分詞器會(huì)將每個(gè)漢字單獨(dú)分為拼音,而我們希望的是每個(gè)詞條形成一組拼音,需要對(duì)拼音分詞器做個(gè)性化定制,形成自定義分詞器。

elasticsearch中分詞器(analyzer)的組成包含三部分:

  • character filters:在tokenizer之前對(duì)特殊字符進(jìn)行處理。例如刪除字符、替換字符
  • tokenizer:將文本按照一定的規(guī)則切割成詞條(term)。例如keyword,就是不分詞;還有ik_smart
  • tokenizer filter:將tokenizer輸出的詞條做進(jìn)一步處理,tokenizer的詞條結(jié)果依然在,只是處理后新加了一些。例如大小寫(xiě)轉(zhuǎn)換、同義詞處理、拼音處理等

拼音分詞器處理文檔流程:

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

自定義分詞器,把ik分詞結(jié)果過(guò)濾成拼音:

settings-analysis下定義分詞器analyzer和filter

PUT /test
{
   //設(shè)置分詞器和過(guò)濾器
  "settings": {
    "analysis": {
      "analyzer": { // 自定義分詞器
        "my_analyzer": {  // 分詞器名稱,這里不需要指定character filters過(guò)濾器,因?yàn)闆](méi)有特殊字符需要處理
          "tokenizer": "ik_max_word",
          "filter": "my_py_filter"    //對(duì)ik分詞結(jié)果做進(jìn)一步處理
        }
      },
      "filter": { // 自定義tokenizer filter
        "my_py_filter": { // 過(guò)濾器名稱
          "type": "pinyin", // 過(guò)濾器類型,填寫(xiě)分詞器名,這里是pinyin
		  "keep_full_pinyin": false,//eg: 劉德華> [liu,de,hua], default: true
          "keep_joined_full_pinyin": true,//eg: 劉德華> [liudehua], default: false
          "keep_original": true,//保留原始輸入,默認(rèn)false
          "limit_first_letter_length": 16,//
          "remove_duplicated_term": true,//
          "none_chinese_pinyin_tokenize": false//?默認(rèn)true。eg: liudehuaalibaba13zhuanghan -> liu,de,hua,a,li,ba,ba,13,zhuang,han
        }
      }
    }
  },

  //創(chuàng)建索引
  "mappings": {
    "properties": {
      "name": {
        "type": "text",
        "analyzer": "my_analyzer",????????//拼音分詞器適合在創(chuàng)建索引時(shí)使用,不能在搜索時(shí)候用
        "search_analyzer": "ik_smart"?????//如果搜索時(shí)用拼音分詞器,搜索"獅子愛(ài)跳舞",會(huì)搜出"虱子"等同音字
      }
    }
  }
}

注意:

拼音分詞器適合在創(chuàng)建索引時(shí)使用,不能在搜索時(shí)候用,如果搜索時(shí)用拼音分詞器,搜索"獅子愛(ài)跳舞",會(huì)搜出"虱子"等同音字。

測(cè)試:自定義分詞器搜索結(jié)果既有ik_smart,還有拼音分詞的結(jié)果

GET /test/_analyze
{
  "analyzer": "my_analyzer"
  , "text": "今天天氣好"
}

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

2.2.2 索引分詞器和搜索分詞器問(wèn)題

在使用ik+拼音過(guò)濾的分詞器時(shí),建議創(chuàng)建的字段的索引分詞器設(shè)為自定義分詞器,搜索分詞器設(shè)為ik分詞器。防止搜索時(shí)搜出拼音諧音的情況。

指定索引、搜索分詞器,并創(chuàng)建索引:

PUT /test
{
   //設(shè)置分詞器和過(guò)濾器
  "settings": {
    "analysis": {
      "analyzer": { // 自定義分詞器
        "my_analyzer": {  // 分詞器名稱,這里不需要指定character filters過(guò)濾器,因?yàn)闆](méi)有特殊字符需要處理
          "tokenizer": "ik_max_word",
          "filter": "my_py_filter"    //對(duì)ik分詞結(jié)果做進(jìn)一步處理
        }
      },
      "filter": { // 自定義tokenizer filter
        "my_py_filter": { // 過(guò)濾器名稱
          "type": "pinyin", // 過(guò)濾器類型,填寫(xiě)分詞器名,這里是pinyin
		  "keep_full_pinyin": false,//eg: 劉德華> [liu,de,hua], default: true
          "keep_joined_full_pinyin": true,//eg: 劉德華> [liudehua], default: false
          "keep_original": true,//保留原始輸入,默認(rèn)false
          "limit_first_letter_length": 16,//
          "remove_duplicated_term": true,//
          "none_chinese_pinyin_tokenize": false//?默認(rèn)true。eg: liudehuaalibaba13zhuanghan -> liu,de,hua,a,li,ba,ba,13,zhuang,han
        }
      }
    }
  },

  //創(chuàng)建索引
  "mappings": {
    "properties": {
      "name": {
        "type": "text",
        "analyzer": "my_analyzer",????????//拼音分詞器適合在創(chuàng)建索引時(shí)使用,不能在搜索時(shí)候用
        "search_analyzer": "ik_smart"?????//如果搜索時(shí)用拼音分詞器,搜索"獅子愛(ài)跳舞",會(huì)搜出"虱子"等同音字
      }
    }
  }
}

建議索引分詞器設(shè)為自定義分詞器,搜索分詞器設(shè)為ik分詞器。防止搜索時(shí)搜出拼音諧音問(wèn)題。

問(wèn)題模擬,索引、搜索都用自定義分詞器:

DELETE /test

PUT /test
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_analyzer":{
          "tokenizer":"ik_smart",
          "filter":"py_filter"
        }
      },
      "filter": {
        "py_filter":{
          "type":"pinyin",
          "keep_full_pinyin": false,
          "keep_joined_full_pinyin": true,
          "keep_original": true,
          "limit_first_letter_length": 16,
          "remove_duplicated_term": true,
          "none_chinese_pinyin_tokenize": false
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "name":{
        "type": "text",
        "analyzer": "my_analyzer"    //統(tǒng)一ik+拼音過(guò)濾
      }
    }
  }
}
POST /test/_doc/1
{
  "name":"獅子"
}

POST /test/_doc/2
{
  "name":"師資"
}

GET /test/_search
{
  "query": {
    "match": {
      "name": "獅子愛(ài)跳舞"
    }
  }
}

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

可以看見(jiàn),明明搜索的是獅子,卻搜出了諧音師資。因?yàn)樗阉鳌蔼{子愛(ài)跳舞”時(shí),ik+拼音過(guò)濾后的結(jié)果里有“shizi”,而師資的分詞結(jié)果也有“shizi”,所以就搜出了師資。

如果搜索“shizi”,出現(xiàn)結(jié)果正常,是獅子和師資。

解決辦法:索引分詞器設(shè)為自定義分詞器,搜索分詞器設(shè)為ik分詞器。防止搜索時(shí)搜出拼音諧音問(wèn)題。

明顯不是我們想要的,所以要讓它搜索時(shí)候只用ik分詞,不要拼音過(guò)濾就搜不出諧音了,而添加新文檔時(shí)還要它進(jìn)行分詞拼音,以便于我們可以搜拼音時(shí)也能搜出對(duì)應(yīng)字段。

PUT /test
{
   //設(shè)置分詞器和過(guò)濾器
  "settings": {
     ...自定義分詞器
  },

  //創(chuàng)建索引
  "mappings": {
    "properties": {
      "name": {
        "type": "text",
        "analyzer": "my_analyzer",????????//創(chuàng)建文檔時(shí)自定義分詞器,ik+拼音過(guò)濾
        "search_analyzer": "ik_smart"?????//搜索時(shí)只用ik分詞器
      }
    }
  }
}

總結(jié):

如何使用拼音分詞器?

  • ①下載pinyin分詞器

  • ②解壓并放到elasticsearch的plugin目錄

  • ③重啟即可

如何自定義分詞器?

  • ①創(chuàng)建索引庫(kù)時(shí),在settings中配置,可以包含三部分

  • ②character filter

  • ③tokenizer

  • ④filter

拼音分詞器注意事項(xiàng)?

  • 為了避免搜索到同音字,搜索時(shí)不要使用拼音分詞器

2.3.自動(dòng)補(bǔ)全查詢,conmpetion suggester

補(bǔ)全效果預(yù)覽:錄入?["天蒼蒼", "野茫茫"]、["天府", "天下"]、["世界", "黃天"]。suggest搜索“天”,可以搜索出前兩個(gè)文檔。suggest搜索“天蒼”,只能搜索出第一個(gè)文檔。

elasticsearch提供了Completion Suggester查詢來(lái)實(shí)現(xiàn)自動(dòng)補(bǔ)全功能。這個(gè)查詢會(huì)匹配以用戶輸入內(nèi)容開(kāi)頭的詞條并返回。為了提高補(bǔ)全查詢的效率,對(duì)于文檔中字段的類型有一些約束:

  • 參與補(bǔ)全查詢的字段必須是completion類型,數(shù)據(jù)是字符串?dāng)?shù)組。completion譯為完成

  • 字段的內(nèi)容一般是用來(lái)補(bǔ)全的多個(gè)詞條形成的數(shù)組

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

創(chuàng)建索引庫(kù):

// 創(chuàng)建索引庫(kù)
PUT test
{
  "mappings": {
    "properties": {
      "title":{
        "type": "completion"    
      }
    }
  }
}

插入數(shù)據(jù):

// 示例數(shù)據(jù)
POST test/_doc
{
  "title": ["天蒼蒼", "野茫茫"]
}
POST test/_doc
{
  "title": ["天府", "天下"]
}
POST test/_doc
{
  "title": ["世界", "黃天"]
}

自動(dòng)補(bǔ)全查詢:

// 自動(dòng)補(bǔ)全查詢
GET /test/_search
{
  "suggest": {
    "titleSuggest": {    //例如自定義查詢名稱
      "text": "天", // 關(guān)鍵字
      "completion": {
        "field": "title", // 補(bǔ)全查詢的字段,例如title
        "skip_duplicates": true, // 跳過(guò)重復(fù)的
        "size": 10 // 獲取前10條結(jié)果
      }
    }
  }
}

搜索結(jié)果:

{
  "took" : 275,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 0,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "suggest" : {
    "my_suggest" : [
      {
        "text" : "天",
        "offset" : 0,
        "length" : 1,
        "options" : [
          {
            "text" : "天下",
            "_index" : "test2",
            "_type" : "_doc",
            "_id" : "AEutP4MBg4Wtm5vtyLdE",
            "_score" : 1.0,
            "_source" : {
              "name" : [
                "天府",
                "天下"
              ]
            }
          },
          {
            "text" : "天蒼蒼",
            "_index" : "test2",
            "_type" : "_doc",
            "_id" : "AUutP4MBg4Wtm5vtyLdI",
            "_score" : 1.0,
            "_source" : {
              "name" : [
                "天蒼蒼",
                "野茫茫"
              ]
            }
          }
        ]
      }
    ]
  }
}

2.4.實(shí)現(xiàn)酒店搜索框自動(dòng)補(bǔ)全

現(xiàn)在,我們的hotel索引庫(kù)還沒(méi)有設(shè)置拼音分詞器,需要修改索引庫(kù)中的配置。但是我們知道索引庫(kù)是無(wú)法修改的,只能刪除然后重新創(chuàng)建。

另外,我們需要添加一個(gè)字段,用來(lái)做自動(dòng)補(bǔ)全,將brand、suggestion、city等都放進(jìn)去,作為自動(dòng)補(bǔ)全的提示。

因此,總結(jié)一下,我們需要做的事情包括:

  1. 修改hotel索引庫(kù)結(jié)構(gòu),設(shè)置自定義拼音分詞器

  2. 修改索引庫(kù)的name、all字段,使用自定義分詞器

  3. 索引庫(kù)添加一個(gè)新字段suggestion,類型為completion類型,使用自定義的分詞器

  4. 給HotelDoc類添加suggestion字段,內(nèi)容包含brand、business

  5. 重新導(dǎo)入數(shù)據(jù)到hotel庫(kù)

2.4.1.創(chuàng)建新索引庫(kù),使用自定義分詞器

①ik+拼音過(guò)濾分詞器,給ik分詞設(shè)置自定義過(guò)濾器,給分詞進(jìn)一步處理成拼音。索引使用自定義分詞器,搜索使用ik分詞器。②關(guān)鍵字+拼音過(guò)濾分詞器,代碼補(bǔ)全使用的分詞器。 ?

代碼如下:

//酒店數(shù)據(jù)索引庫(kù)。先刪除舊的,再新的
DELETE /hotel
PUT /hotel
{
  "settings": {
    "analysis": {
      "analyzer": {
        "text_anlyzer": {    //ik+拼音過(guò)濾
          "tokenizer": "ik_max_word",
          "filter": "py"
        },
        "completion_analyzer": {    //keyword+拼音過(guò)濾,相當(dāng)于又保持關(guān)鍵詞,又新加定制版拼音分詞
          "tokenizer": "keyword",
          "filter": "py"
        }
      },
      "filter": {
        "py": {
          "type": "pinyin",
          "keep_full_pinyin": false,
          "keep_joined_full_pinyin": true,
          "keep_original": true,
          "limit_first_letter_length": 16,
          "remove_duplicated_term": true,
          "none_chinese_pinyin_tokenize": false
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "id":{
        "type": "keyword"
      },
      "name":{
        "type": "text",
        "analyzer": "text_anlyzer",        //新建文檔時(shí)分詞器用ik+拼音過(guò)濾
        "search_analyzer": "ik_smart",    //搜索分詞器用ik
        "copy_to": "all"
      },
      "address":{
        "type": "keyword",
        "index": false
      },
      "price":{
        "type": "integer"
      },
      "score":{
        "type": "integer"
      },
      "brand":{
        "type": "keyword",
        "copy_to": "all"
      },
      "city":{
        "type": "keyword"
      },
      "starName":{
        "type": "keyword"
      },
      "business":{
        "type": "keyword",
        "copy_to": "all"
      },
      "location":{
        "type": "geo_point"
      },
      "pic":{
        "type": "keyword",
        "index": false
      },
      "all":{
        "type": "text",
        "analyzer": "text_anlyzer",
        "search_analyzer": "ik_smart"
      },
      "suggestion":{    //補(bǔ)全字段suggestion
          "type": "completion",    //補(bǔ)全字段類型必須completion
          "analyzer": "completion_analyzer"    //補(bǔ)全分詞器,keyword+拼音過(guò)濾
      }
    }
  }
}

2.4.2.HotelDoc實(shí)體類添加suggestion字段

HotelDoc中要添加一個(gè)字段,用來(lái)做自動(dòng)補(bǔ)全,內(nèi)容可以是酒店品牌、城市、商圈等信息。按照自動(dòng)補(bǔ)全字段的要求,最好是這些字段的數(shù)組。

因此我們?cè)贖otelDoc中添加一個(gè)suggestion字段,類型為List<String>,然后將brand、city、business等信息放到里面。

代碼如下:

package cn.itcast.hotel.pojo;

import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

@Data
@NoArgsConstructor
public class HotelDoc {
    private Long id;
    private String name;
    private String address;
    private Integer price;
    private Integer score;
    private String brand;
    private String city;
    private String starName;
    private String business;	//商圈,例如虹橋機(jī)場(chǎng)/國(guó)家會(huì)展中心
    private String location;
    private String pic;
    private Object distance;
    private Boolean isAD;
    private List<String> suggestion;	//放自動(dòng)補(bǔ)全的list列表,這里只補(bǔ)全搜索商圈和品牌

    public HotelDoc(Hotel hotel) {
        this.id = hotel.getId();
        this.name = hotel.getName();
        this.address = hotel.getAddress();
        this.price = hotel.getPrice();
        this.score = hotel.getScore();
        this.brand = hotel.getBrand();
        this.city = hotel.getCity();
        this.starName = hotel.getStarName();
        this.business = hotel.getBusiness();
        this.location = hotel.getLatitude() + ", " + hotel.getLongitude();
        this.pic = hotel.getPic();
        // 組裝suggestion,把品牌和商圈放進(jìn)去
        if(this.business.contains("/")){
            // business有多個(gè)值,例如“例如虹橋機(jī)場(chǎng)/國(guó)家會(huì)展中心”,需要切割
            String[] arr = this.business.split("/");
            // 添加元素
            this.suggestion = new ArrayList<>();
            this.suggestion.add(this.brand);
            Collections.addAll(this.suggestion, arr);
        }else {
            this.suggestion = Arrays.asList(this.brand, this.business);
        }
    }
}

2.4.3.重新導(dǎo)入MySQL數(shù)據(jù)到es索引庫(kù)

重新執(zhí)行之前編寫(xiě)的導(dǎo)入數(shù)據(jù)功能

    @Test
    public void bulk() throws IOException {
        List<Hotel> hotels = hotelService.list();
        for(Hotel hotel:hotels){
            HotelDoc hotelDoc = new HotelDoc(hotel);
            client.index(new IndexRequest("hotel").id(hotel.getId().toString()).source(JSON.toJSONString(hotelDoc),XContentType.JSON),RequestOptions.DEFAULT);
        }

    }

查詢所有 ,可以看到新的酒店數(shù)據(jù)中包含了suggestion:

GET /hotel/_search
{
  "query": {
    "match_all": {}
  }
}

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

2.4.4 測(cè)試補(bǔ)全,suggest搜索"rj"結(jié)果“如家”的文檔

因?yàn)?strong>suggestion字段自定義分詞器是keyword+拼音過(guò)濾,所以搜索“如”搜不出“如家”。搜索“如家”可以搜索出brand為“如家”的一條文檔(搜索條件有跳過(guò)重復(fù))。搜索“rj”,可以搜索出brand為“如家”的文檔

測(cè)試:?

GET /hotel/_search
{
  "suggest": {
    "my_suggest": {
      "text": "rj",
      "completion":{
        "field": "suggestion", 
        "skip_duplicates": true, 
        "size": 10
      }
    }
  }
}

因?yàn)橹付ㄌ^(guò)重復(fù),所以搜索結(jié)果僅一條:

{
  "took" : 6,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 0,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "suggest" : {
    "my_suggest" : [
      {
        "text" : "如家",
        "offset" : 0,
        "length" : 2,
        "options" : [
          {
            "text" : "如家",
            "_index" : "hotel",
            "_type" : "_doc",
            "_id" : "415600",
            "_score" : 1.0,
            "_source" : {
              "address" : "三間房鄉(xiāng)褡褳坡村青年溝西側(cè)558號(hào)",
              "brand" : "如家",
              "business" : "傳媒大學(xué)/管莊地區(qū)",
              "city" : "北京",
              "id" : 415600,
              "location" : "39.923212, 116.560023",
              "name" : "如家酒店(北京朝陽(yáng)北路傳媒大學(xué)褡褳坡地鐵站店)",
              "pic" : "https://m.tuniucdn.com/fb3/s1/2n9c/3NezpxNZWQMdNXibwbMkQuAZjDyJ_w200_h200_c1_t0.jpg",
              "price" : 259,
              "score" : 47,
              "starName" : "二鉆",
              "suggestion" : [
                "如家",
                "傳媒大學(xué)",
                "管莊地區(qū)"
              ]
            }
          }
        ]
      }
    ]
  }
}

2.4.5.自動(dòng)補(bǔ)全查詢的JavaAPI,SuggestBuilder()

之前我們學(xué)習(xí)了自動(dòng)補(bǔ)全查詢的DSL,而沒(méi)有學(xué)習(xí)對(duì)應(yīng)的JavaAPI,這里給出一個(gè)示例:

suggest和query是平級(jí)的。?

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

而自動(dòng)補(bǔ)全的結(jié)果也比較特殊,解析的代碼如下:

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

2.4.6.實(shí)現(xiàn)旅游項(xiàng)目搜索框自動(dòng)補(bǔ)全

查看前端頁(yè)面,可以發(fā)現(xiàn)當(dāng)我們?cè)谳斎肟蜴I入時(shí),前端會(huì)發(fā)起ajax請(qǐng)求:

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

返回值是補(bǔ)全詞條的集合,類型為List<String>

1)在cn.itcast.hotel.web包下的HotelController中添加新接口,接收新的請(qǐng)求:

@GetMapping("suggestion")
public List<String> getSuggestions(@RequestParam("key") String prefix) {
    return hotelService.getSuggestions(prefix);
}

2)在cn.itcast.hotel.service包下的IhotelService中添加方法:

List<String> getSuggestions(String prefix);

3)在cn.itcast.hotel.service.impl.HotelService中實(shí)現(xiàn)該方法:

建議截圖補(bǔ)全的es代碼,貼到屏幕上,層層解析?

@Override
public List<String> getSuggestions(String prefix) {
    try {
        // 1.準(zhǔn)備Request
        SearchRequest request = new SearchRequest("hotel");
        // 2.準(zhǔn)備DSL
        request.source().suggest(new SuggestBuilder().addSuggestion(    //new SuggestBuilder()不是SuggestBuilders
            "suggestions",    //自定義補(bǔ)全的名字,后面根據(jù)它解析response
            SuggestBuilders.completionSuggestion("suggestion")    //字段名
            .prefix(prefix)    //需要補(bǔ)全的文本
            .skipDuplicates(true)
            .size(10)
        ));
        // 3.發(fā)起請(qǐng)求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        // 4.解析結(jié)果
        Suggest suggest = response.getSuggest();
        // 4.1.根據(jù)補(bǔ)全查詢名稱,獲取補(bǔ)全結(jié)果,注意返回值和ctrl+alt+v生成的內(nèi)容不一樣
        CompletionSuggestion suggestions = suggest.getSuggestion("suggestions");
        // 4.2.獲取options
        List<CompletionSuggestion.Entry.Option> options = suggestions.getOptions();
        // 4.3.遍歷
        List<String> list = new ArrayList<>(options.size());
        for (CompletionSuggestion.Entry.Option option : options) {
            String text = option.getText().toString();
            list.add(text);
        }
        return list;
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

測(cè)試成功:

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

3.mysql與es數(shù)據(jù)同步

elasticsearch中的酒店數(shù)據(jù)來(lái)自于mysql數(shù)據(jù)庫(kù),因此mysql數(shù)據(jù)發(fā)生改變時(shí),elasticsearch也必須跟著改變,這個(gè)就是elasticsearch與mysql之間的數(shù)據(jù)同步。

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

3.1.思路分析

常見(jiàn)的數(shù)據(jù)同步方案有三種:

  • 同步調(diào)用
  • 異步通知
  • 監(jiān)聽(tīng)binlog

3.1.1.方案一:同步調(diào)用

方案一:同步調(diào)用

管理端只能訪問(wèn)mysql,用戶端只能訪問(wèn)es,兩者間隔離,符合微服務(wù)規(guī)范。?

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

基本步驟如下:

  • hotel-demo對(duì)外提供接口,用來(lái)修改elasticsearch中的數(shù)據(jù)
  • 酒店管理服務(wù)在完成數(shù)據(jù)庫(kù)操作后,直接調(diào)用hotel-demo提供的接口,

缺點(diǎn):耦合度高?

3.1.2.方案二:異步通知

方案二:異步通知

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

流程如下:

  • hotel-admin對(duì)mysql數(shù)據(jù)庫(kù)數(shù)據(jù)完成增、刪、改后,發(fā)送MQ消息
  • hotel-demo監(jiān)聽(tīng)MQ,接收到消息后完成elasticsearch數(shù)據(jù)修改

優(yōu)點(diǎn):性能高,耦合度低

缺點(diǎn):依賴于mq消息隊(duì)列可靠性?

3.1.3.方案三:canal監(jiān)聽(tīng)mysql的binlog

canal譯為管道,運(yùn)河。

回顧主從復(fù)制,主庫(kù)開(kāi)啟binlog,從庫(kù)根據(jù)主庫(kù)binlog的增刪改信息,進(jìn)行相同操作。

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

流程如下:

  • 給mysql開(kāi)啟binlog功能
  • mysql完成增、刪、改操作都會(huì)記錄在binlog中
  • hotel-demo基于canal監(jiān)聽(tīng)binlog變化,實(shí)時(shí)更新elasticsearch中的內(nèi)容

優(yōu)點(diǎn):耦合度最低

缺點(diǎn):mysql壓力增加?

3.1.4.三種方案優(yōu)缺點(diǎn)總結(jié)

方式一:同步調(diào)用

  • 優(yōu)點(diǎn):實(shí)現(xiàn)簡(jiǎn)單,粗暴
  • 缺點(diǎn):業(yè)務(wù)耦合度高

方式二:異步通知

  • 優(yōu)點(diǎn):低耦合,實(shí)現(xiàn)難度一般
  • 缺點(diǎn):依賴mq的可靠性

方式三:監(jiān)聽(tīng)binlog

  • 優(yōu)點(diǎn):完全解除服務(wù)間耦合
  • 缺點(diǎn):開(kāi)啟binlog增加數(shù)據(jù)庫(kù)負(fù)擔(dān)、實(shí)現(xiàn)復(fù)雜度高

3.2.MQ實(shí)現(xiàn)數(shù)據(jù)同步

3.2.1.思路

利用課前資料提供的hotel-admin項(xiàng)目作為酒店管理的微服務(wù)。當(dāng)酒店數(shù)據(jù)發(fā)生增、刪、改時(shí),要求對(duì)elasticsearch中數(shù)據(jù)也要完成相同操作。

使用RabbitMQ的發(fā)布/訂閱模型topic話題模式,支持不同的消息根據(jù)routingKey被不同的隊(duì)列消費(fèi)。先聲明交換機(jī)、隊(duì)列,增刪兩個(gè)routingKey。只需要增刪兩個(gè)隊(duì)列,restapi里增改是一致的,id存在則修改,id不存在則新增。 ?

忘了就回顧:SpringCloud基礎(chǔ)4——RabbitMQ和SpringAMQP?

步驟:

  • 導(dǎo)入課前資料提供的hotel-admin項(xiàng)目,啟動(dòng)并測(cè)試酒店數(shù)據(jù)的CRUD

  • 聲明exchange、queue、RoutingKey

  • 在hotel-admin中的增、刪、改業(yè)務(wù)中完成消息發(fā)送

  • 在hotel-demo中完成消息監(jiān)聽(tīng),并更新elasticsearch中數(shù)據(jù)

  • 啟動(dòng)并測(cè)試數(shù)據(jù)同步功能

3.2.2.導(dǎo)入hotel-admin后臺(tái)管理端、修改pom和yml

導(dǎo)入課前資料提供的hotel-admin項(xiàng)目:

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

修改pom

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.2</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.2.11</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>

修改yml:

server:
  port: 8099
spring:
  datasource:
    druid:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://localhost:3306/heima?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true
      username: root
      password: 1234
  main:
    banner-mode: off
  rabbitmq:
    host: 192.168.200.131
    port: 5672
    username: itcast
    password: 123321
    virtual-host: / #虛擬主機(jī)
#logging:
#  level:
#    cn.itcast: debug
#  pattern:
#    dateformat: MM-dd HH:mm:ss:SSS

#  type-aliases-package:com.vince.hotel.pojo
mybatis-plus:
  configuration:
    map-underscore-to-camel-case: true
  global-config:
    banner: false

?運(yùn)行后,訪問(wèn) http://localhost:8099

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

其中包含了酒店的CRUD功能:

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

3.2.3.聲明交換機(jī)、隊(duì)列

MQ結(jié)構(gòu)如圖:

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

0)開(kāi)啟RabbitMQ

docker ps -a
docker start 容器名

管理端:

http://ip地址:15672/

SpringCloud基礎(chǔ)4——RabbitMQ_springcloud rabbitmq_vincewm的博客-CSDN博客

1)引入依賴、yml

在hotel-admin、hotel-demo中引入rabbitmq的依賴:

<!--amqp-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

yml:

server:
  port: 8099
spring:
  datasource:
    druid:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://localhost:3306/heima?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true
      username: root
      password: 1234
  main:
    banner-mode: off
  rabbitmq:
    host: 192.168.200.131
    port: 5672
    username: itcast
    password: 123321
    virtual-host: / #虛擬主機(jī)
#logging:
#  level:
#    cn.itcast: debug
#  pattern:
#    dateformat: MM-dd HH:mm:ss:SSS

#  type-aliases-package:com.vince.hotel.pojo
mybatis-plus:
  configuration:
    map-underscore-to-camel-case: true
  global-config:
    banner: false

2)常量類,聲明隊(duì)列交換機(jī)名稱

在hotel-admin和hotel-demo中的cn.itcast.hotel.constatnts包下新建一個(gè)類MqConstants

package cn.itcast.hotel.constants;

    public class MqConstants {
    /**
     * 交換機(jī)
     */
    public final static String HOTEL_EXCHANGE = "hotel.topic";
    /**
     * 監(jiān)聽(tīng)新增和修改的隊(duì)列
     */
    public final static String HOTEL_INSERT_QUEUE = "hotel.insert.queue";
    /**
     * 監(jiān)聽(tīng)刪除的隊(duì)列
     */
    public final static String HOTEL_DELETE_QUEUE = "hotel.delete.queue";
    /**
     * 新增或修改的RoutingKey
     */
    public final static String HOTEL_INSERT_KEY = "hotel.insert";
    /**
     * 刪除的RoutingKey
     */
    public final static String HOTEL_DELETE_KEY = "hotel.delete";
}

3)聲明隊(duì)列交換機(jī)

topic模式回顧:話題模式,通配符。Topic類型的ExchangeDirect相比,都是可以根據(jù)RoutingKey把消息路由到不同的隊(duì)列。只不過(guò)Topic類型Exchange可以讓隊(duì)列在綁定Routing key?的時(shí)候使用通配符!

也可以在接收消息時(shí),使用注解方式@RabbitListener的bindings,適用于消息隊(duì)列少的情況:

@RabbitListener(bindings = @QueueBinding(
    value = @Queue(name = "topic.queue1"),
    exchange = @Exchange(name = "itcast.topic", type = ExchangeTypes.TOPIC),
    key = "china.#"
))
public void listenTopicQueue1(String msg){
    System.out.println("消費(fèi)者接收到topic.queue1的消息:【" + msg + "】");
}

?在config包下創(chuàng)建MqConfig,聲明隊(duì)列、交換機(jī):

package cn.itcast.hotel.config;

import cn.itcast.hotel.constants.MqConstants;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MqConfig {
    @Bean
    public TopicExchange topicExchange(){
        //第二個(gè)參數(shù)為是否持久化,第三個(gè)參數(shù)為是否自動(dòng)刪除。兩個(gè)參數(shù)默認(rèn)值就是持久化、不自動(dòng)刪除
        return new TopicExchange(MqConstants.HOTEL_EXCHANGE, true, false);
    }

    @Bean
    public Queue insertQueue(){
        return new Queue(MqConstants.HOTEL_INSERT_QUEUE, true);
    }

    @Bean
    public Queue deleteQueue(){
        return new Queue(MqConstants.HOTEL_DELETE_QUEUE, true);
    }

    @Bean
    public Binding insertQueueBinding(){
        return BindingBuilder.bind(insertQueue()).to(topicExchange()).with(MqConstants.HOTEL_INSERT_KEY);
    }

    @Bean
    public Binding deleteQueueBinding(){
        return BindingBuilder.bind(deleteQueue()).to(topicExchange()).with(MqConstants.HOTEL_DELETE_KEY);
    }
}

為什么只需要增刪兩個(gè)隊(duì)列,不用“改”?隊(duì)列?

在RestClient的API中,全量修改與新增的API完全一致,判斷依據(jù)是ID:

  • 如果新增時(shí),ID已經(jīng)存在,則修改
  • 如果新增時(shí),ID不存在,則新增

3.2.4.后臺(tái)端發(fā)送MQ消息

在hotel-admin中的增、刪、改業(yè)務(wù)中分別發(fā)送MQ消息,消息內(nèi)容為id,到時(shí)候用戶端根據(jù)id增刪改

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

3.2.5.用戶端接收MQ消息

管理端hotel-admin不能直接調(diào)用es,想對(duì)es實(shí)現(xiàn)增刪改要通過(guò)給用戶端hotel-demo發(fā)送新增(修改)、刪除消息。

hotel-demo接收到MQ消息要做的事情包括:

  • 新增消息:根據(jù)傳遞的hotel的id查詢hotel信息,然后新增一條數(shù)據(jù)到索引庫(kù)
  • 刪除消息:根據(jù)傳遞的hotel的id刪除索引庫(kù)中的一條數(shù)據(jù)

0) 環(huán)境準(zhǔn)備

pom

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>

yml

spring:
  rabbitmq:
    host: 192.168.200.131
    port: 5672
    username: itcast
    password: 123321
    virtual-host: / #虛擬主機(jī)

復(fù)制管理端的MqConstants.java和MqConfig到用戶端

1)service接口新增新增、刪除業(yè)務(wù)

首先在hotel-demo的cn.itcast.hotel.service包下的IHotelService新增新增、刪除業(yè)務(wù)

//mp的增刪方法是saveById和removeById,所以這里并不沖突
void deleteById(Long id);

void insertById(Long id);

2)service實(shí)現(xiàn)類實(shí)現(xiàn)業(yè)務(wù)

給hotel-demo中的cn.itcast.hotel.service.impl包下的HotelService中實(shí)現(xiàn)業(yè)務(wù):

//mp的增刪方法是saveById和removeById,所以這里并不沖突
@Override
public void deleteById(Long id) {
    try {
        // 1.準(zhǔn)備Request
        DeleteRequest request = new DeleteRequest("hotel", id.toString());
        // 2.發(fā)送請(qǐng)求
        client.delete(request, RequestOptions.DEFAULT);
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

@Override
public void insertById(Long id) {
    try {
        // 0.根據(jù)id查詢酒店數(shù)據(jù)
        Hotel hotel = getById(id);
        // 轉(zhuǎn)換為文檔類型
        HotelDoc hotelDoc = new HotelDoc(hotel);

        // 1.準(zhǔn)備Request對(duì)象
        IndexRequest request = new IndexRequest("hotel").id(hotel.getId().toString());
        // 2.準(zhǔn)備Json文檔
        request.source(JSON.toJSONString(hotelDoc), XContentType.JSON);
        // 3.發(fā)送請(qǐng)求
        client.index(request, RequestOptions.DEFAULT);
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

坑點(diǎn):刪除文檔的request別忘了設(shè)置id,不然會(huì)刪除所有數(shù)據(jù)。

3)編寫(xiě)監(jiān)聽(tīng)器

mq包下新增一個(gè)類:

package cn.itcast.hotel.mq;

import cn.itcast.hotel.constants.MqConstants;
import cn.itcast.hotel.service.IHotelService;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
//別忘了@Component,被ioc容器管理,一直監(jiān)聽(tīng)
@Component
public class HotelListener {

    @Autowired
    private IHotelService hotelService;

    /**
     * 監(jiān)聽(tīng)酒店新增或修改的業(yè)務(wù)
     * @param id 酒店id
     */
    @RabbitListener(queues = MqConstants.HOTEL_INSERT_QUEUE)
    public void listenHotelInsertOrUpdate(Long id){
        hotelService.insertById(id);
    }

    /**
     * 監(jiān)聽(tīng)酒店刪除的業(yè)務(wù)
     * @param id 酒店id
     */
    @RabbitListener(queues = MqConstants.HOTEL_DELETE_QUEUE)
    public void listenHotelDelete(Long id){
        hotelService.deleteById(id);
    }
}

3.2.6 測(cè)試

運(yùn)行管理端和用戶端服務(wù)后,打開(kāi)rabbitmq服務(wù)端: http://ip地址:15672

可以看到隊(duì)列、交換機(jī)創(chuàng)建成功:

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

?ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

交換機(jī)綁定關(guān)系:

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

先用戶端搜索一個(gè)酒店,然后在管理端修改酒店信息 :

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

可以看到隊(duì)列的消息記錄:

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

用戶端搜索后的數(shù)據(jù)也改變了:

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

再刪除酒店,發(fā)現(xiàn)成功。

3.2.7.vue插件實(shí)現(xiàn)快速拷貝數(shù)據(jù)到表單

安裝地址

https://chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd?hl=zh

拷貝數(shù)據(jù)并保存的辦法:

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

粘貼即可快速填充表單:

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

4.集群

4.0.概述?

單機(jī)的elasticsearch做數(shù)據(jù)存儲(chǔ),必然面臨兩個(gè)問(wèn)題:海量數(shù)據(jù)存儲(chǔ)問(wèn)題、單點(diǎn)故障問(wèn)題。

  • 海量數(shù)據(jù)存儲(chǔ)問(wèn)題:索引庫(kù)從邏輯上拆分為N個(gè)分片(shard),存儲(chǔ)到多個(gè)節(jié)點(diǎn)
  • 單點(diǎn)故障問(wèn)題:將分片數(shù)據(jù)在不同節(jié)點(diǎn)備份(replica )?

ES集群相關(guān)概念:

一個(gè)集群里有多個(gè)節(jié)點(diǎn),每個(gè)節(jié)點(diǎn)都是一個(gè)es實(shí)例,?每個(gè)節(jié)點(diǎn)保存了自己的分片和一個(gè)其他節(jié)點(diǎn)備份的分片。

  • 集群(cluster):一組擁有共同的 集群名 的 節(jié)點(diǎn)。

  • 節(jié)點(diǎn)(node)?:集群中的一個(gè) Elasticearch 實(shí)例

  • 分片(shard):索引可以被拆分為不同的部分進(jìn)行存儲(chǔ),稱為分片。在集群環(huán)境下,一個(gè)索引的不同分片可以拆分到不同的節(jié)點(diǎn)中

    解決問(wèn)題:數(shù)據(jù)量太大,單點(diǎn)存儲(chǔ)量有限的問(wèn)題。

    ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

    此處,我們把數(shù)據(jù)分成3片:shard0、shard1、shard2

  • 主分片(Primary shard):相對(duì)于副本分片的定義。

  • 副本分片(Replica shard):每個(gè)主分片可以有一個(gè)或者多個(gè)副本,數(shù)據(jù)和主分片一樣。

    ?

數(shù)據(jù)備份可以保證高可用,但是每個(gè)分片備份一份,所需要的節(jié)點(diǎn)數(shù)量就會(huì)翻一倍,成本實(shí)在是太高了!

為了在高可用和成本間尋求平衡,我們可以這樣做:

  • 首先對(duì)數(shù)據(jù)分片,存儲(chǔ)到不同節(jié)點(diǎn)
  • 然后對(duì)每個(gè)分片進(jìn)行備份,放到對(duì)方節(jié)點(diǎn),完成互相備份

這樣可以大大減少所需要的服務(wù)節(jié)點(diǎn)數(shù)量,如圖,我們以3分片,每個(gè)分片備份一份為例:

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

現(xiàn)在,每個(gè)分片都有1個(gè)備份,存儲(chǔ)在3個(gè)節(jié)點(diǎn):

  • 節(jié)點(diǎn)node0:保存了分片0和1
  • node1:保存了分片0和2
  • node2:保存了分片1和2

4.1.搭建ES集群

4.1.0.Docker Compose介紹

Docker Compose是一個(gè)用來(lái)定義和運(yùn)行復(fù)雜應(yīng)用的Docker工具,將一個(gè)或多個(gè)容器組合成一個(gè)完整的應(yīng)用程序。一個(gè)使用Docker容器的應(yīng)用,通常由多個(gè)容器組成。使用Docker Compose不再需要使用shell腳本來(lái)啟動(dòng)容器。

Compose 通過(guò)一個(gè)配置文件來(lái)管理多個(gè)Docker容器,在配置文件中,所有的容器通過(guò)services來(lái)定義,然后使用docker-compose腳本來(lái)啟動(dòng),停止和重啟應(yīng)用,和應(yīng)用中的服務(wù)以及所有依賴服務(wù)的容器,非常適合組合使用多個(gè)容器進(jìn)行開(kāi)發(fā)的場(chǎng)景。

Docker Compose 使用的三個(gè)步驟:

  1. 使用 Dockerfile 定義應(yīng)用程序的環(huán)境
  2. 使用 docker-compose.yml 定義構(gòu)成應(yīng)用程序的服務(wù),這樣它們可以在隔離環(huán)境中一起運(yùn)行
  3. 執(zhí)行 docker-compose up 命令(后面加-d是在后臺(tái)運(yùn)行)來(lái)啟動(dòng)并運(yùn)行整個(gè)應(yīng)用程序

4.1.1.創(chuàng)建es集群

創(chuàng)建同一個(gè)集群的三個(gè)節(jié)點(diǎn),每個(gè)節(jié)點(diǎn)都是一個(gè)es實(shí)例:

①首先編寫(xiě)一個(gè)docker-compose.yml文件,上傳到/root,內(nèi)容如下:

注意端口占用問(wèn)題:ports:-9200:9200,左邊是centos的端口,右邊是容器內(nèi)部端口,只有左邊會(huì)發(fā)生端口占用問(wèn)題,前面安裝過(guò)單點(diǎn)es的默認(rèn)接口是9200,注意一下。

#創(chuàng)建三個(gè)es容器,容器名和節(jié)點(diǎn)名都是es01、es02、es03。

version: '2.2'
services:
  es01:
    image: elasticsearch:7.12.1    #鏡像名稱
    container_name: es01    #容器名稱
    environment:
      - node.name=es01
#集群名稱。三個(gè)容器集群名稱一樣,es會(huì)自動(dòng)把他們組裝成一個(gè)集群。
      - cluster.name=es-docker-cluster    
#集群中其他節(jié)點(diǎn)的ip地址;docker容器之間通過(guò)名字直接相互訪問(wèn)
      - discovery.seed_hosts=es02,es03	
#集群中可以參與選舉的主節(jié)點(diǎn)
      - cluster.initial_master_nodes=es01,es02,es03
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"    #內(nèi)存大小,最小和最大內(nèi)存
    volumes:
      - data01:/usr/share/elasticsearch/data
    ports:
      - 9200:9200    #對(duì)外端口9200:對(duì)內(nèi)端口9200
    networks:
      - elastic
  es02:
    image: elasticsearch:7.12.1
    container_name: es02
    environment:
      - node.name=es02
#集群名稱。三個(gè)容器集群名稱一樣,es會(huì)自動(dòng)把他們組裝成一個(gè)集群。
      - cluster.name=es-docker-cluster
      - discovery.seed_hosts=es01,es03
      - cluster.initial_master_nodes=es01,es02,es03
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    volumes:
      - data02:/usr/share/elasticsearch/data
    ports:
      - 9201:9200
    networks:
      - elastic
  es03:
    image: elasticsearch:7.12.1
    container_name: es03
    environment:
      - node.name=es03
      - cluster.name=es-docker-cluster
#集群名稱。三個(gè)容器集群名稱一樣,es會(huì)自動(dòng)把他們組裝成一個(gè)集群。
      - discovery.seed_hosts=es01,es02
      - cluster.initial_master_nodes=es01,es02,es03
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    volumes:
      - data03:/usr/share/elasticsearch/data
    networks:
      - elastic
    ports:
      - 9202:9200
volumes:
  data01:
    driver: local
  data02:
    driver: local
  data03:
    driver: local

networks:
  elastic:
    driver: bridge

②修改權(quán)限:?

es運(yùn)行需要修改一些linux系統(tǒng)權(quán)限,修改/etc/sysctl.conf文件

vi /etc/sysctl.conf

添加下面的內(nèi)容,或?qū)⒆⑨尨蜷_(kāi):

vm.max_map_count=262144

然后執(zhí)行命令,讓配置生效

sysctl -p

③通過(guò)docker-compose up啟動(dòng)集群:

docker-compose up -d

4.1.2.集群狀態(tài)監(jiān)控,安裝cerebro

kibana可以監(jiān)控es集群,不過(guò)新版本需要依賴es的x-pack 功能,配置比較復(fù)雜。

這里推薦使用cerebro來(lái)監(jiān)控es集群狀態(tài),官方網(wǎng)址:https://github.com/lmenezes/cerebro

課前資料已經(jīng)提供了安裝包:

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

windows解壓即可使用,非常方便。

解壓好的目錄如下:

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

進(jìn)入對(duì)應(yīng)的bin目錄:

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

雙擊其中的cerebro.bat文件即可啟動(dòng)服務(wù)。

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

訪問(wèn)http://localhost:9000 即可進(jìn)入管理界面:

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

輸入你的elasticsearch的任意節(jié)點(diǎn)的地址和端口,點(diǎn)擊connect即可:

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

綠色的條,代表集群處于綠色(健康狀態(tài))。

4.1.3.創(chuàng)建索引庫(kù)

1)方法一:利用kibana的DevTools創(chuàng)建索引庫(kù)

在DevTools中輸入指令:

PUT /itcast
{
  "settings": {
    "number_of_shards": 3, // 分片數(shù)量,shard譯為碎片
    "number_of_replicas": 1 // 副本數(shù)量,replica譯為副本,復(fù)制品。
  },
  "mappings": {
    "properties": {
      // mapping映射定義 ...
    }
  }
}

2)方法二:利用cerebro創(chuàng)建索引庫(kù)

利用cerebro還可以創(chuàng)建索引庫(kù):

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

填寫(xiě)索引庫(kù)信息:

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

點(diǎn)擊右下角的create按鈕:

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

4.1.4.查看分片效果

回到首頁(yè),即可查看索引庫(kù)分片效果:

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

4.2.集群腦裂問(wèn)題

4.2.1.集群職責(zé)劃分,四種節(jié)點(diǎn)類型

集群職責(zé)劃分:

  • 候選主節(jié)點(diǎn)(master eligible):管理集群狀態(tài),處理索引庫(kù)增刪請(qǐng)求。

  • 數(shù)據(jù)節(jié)點(diǎn)(data):對(duì)記錄的增刪改查。

  • 接待節(jié)點(diǎn)(ingest):數(shù)據(jù)存儲(chǔ)前的預(yù)處理。

協(xié)作節(jié)點(diǎn)(coordinating):將請(qǐng)求路由其他節(jié)點(diǎn),合并處理結(jié)果并返回。

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

主節(jié)點(diǎn)的類型也是master eligible,它是備選主節(jié)點(diǎn)選出來(lái)的。

eligible?譯為合格的,合適的。

ingest譯為接待、吸收。

coordinating譯為協(xié)調(diào),合作。

默認(rèn)情況下,集群中的任何一個(gè)節(jié)點(diǎn)都同時(shí)具備上述四種角色。

但是真實(shí)的集群一定要將集群職責(zé)分離

職責(zé)分離可以讓我們根據(jù)不同節(jié)點(diǎn)的需求分配不同的硬件去部署。而且避免業(yè)務(wù)之間的互相干擾。

典型的es集群職責(zé)劃分:LB是負(fù)載均衡

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

4.2.2.腦裂問(wèn)題

選舉master條件:當(dāng)一個(gè)節(jié)點(diǎn)發(fā)現(xiàn)包括自己在內(nèi)的多數(shù)派的master-eligible節(jié)點(diǎn)認(rèn)為集群沒(méi)有master時(shí),就可以發(fā)起master選舉。

選舉master過(guò)程:

  1. 備選主節(jié)點(diǎn)首先根據(jù)節(jié)點(diǎn)id(第一次啟動(dòng)時(shí)生成的隨機(jī)字符串)排序,第一個(gè)節(jié)點(diǎn)暫定master;

  2. 如果有(n+1)/2個(gè)節(jié)點(diǎn)投票它是mater,并且它自己也給自己投票,則它當(dāng)選master;

  3. 否則就暫定第二個(gè)節(jié)點(diǎn)為master,以此類推。

腦裂:master故障,集群選舉出新master后舊master又恢復(fù)了,導(dǎo)致集群出現(xiàn)了兩個(gè)master。 ?

"腦裂"成因:

  • 網(wǎng)絡(luò)延遲導(dǎo)致誤判:集群間的網(wǎng)絡(luò)延遲導(dǎo)致一些節(jié)點(diǎn)訪問(wèn)不到master, 認(rèn)為master 掛掉了從而選舉出新的master,并對(duì)master上的分片和副本標(biāo)紅,分配新的主分片

  • 主節(jié)點(diǎn)負(fù)載過(guò)高導(dǎo)致誤判:主節(jié)點(diǎn)的角色既為master又為data,訪問(wèn)量較大時(shí)可能會(huì)導(dǎo)致ES停止響應(yīng)造成大面積延遲,此時(shí)其他節(jié)點(diǎn)得不到主節(jié)點(diǎn)的響應(yīng)認(rèn)為主節(jié)點(diǎn)掛掉了,會(huì)重新選取主節(jié)點(diǎn)

  • 內(nèi)存回收導(dǎo)致誤判:data 節(jié)點(diǎn)上的ES進(jìn)程占用的內(nèi)存較大,引發(fā)JVM的大規(guī)模內(nèi)存回收,造成ES進(jìn)程失去響應(yīng),從而長(zhǎng)時(shí)間沒(méi)ping通主節(jié)點(diǎn),導(dǎo)致誤判主節(jié)點(diǎn)下線

  • 主節(jié)點(diǎn)故障。

解決方案:

  • 調(diào)大超時(shí)時(shí)間減少誤判:discovery.zen.ping_timeout節(jié)點(diǎn)狀態(tài)的響應(yīng)時(shí)間,默認(rèn)為3s,可以適當(dāng)調(diào)大,如果master在該響應(yīng)時(shí)間的范圍內(nèi)沒(méi)有做出響應(yīng)應(yīng)答,判斷該節(jié)點(diǎn)已經(jīng)掛掉了。調(diào)大參數(shù)(如6s,discovery.zen.ping_timeout:6),可適當(dāng)減少誤判

  • 選舉觸發(fā)條件:discovery.zen.minimum_master_nodes:(備選主節(jié)點(diǎn)數(shù)量/ 2) +1。該參數(shù)是用于控制選舉條件,只有(n / 2) +1個(gè)備選主節(jié)點(diǎn)認(rèn)為主節(jié)點(diǎn)故障才開(kāi)始選舉。在es7.0以后,已經(jīng)成為默認(rèn)配置,因此一般不會(huì)發(fā)生腦裂問(wèn)題

  • master和data分離:即master節(jié)點(diǎn)與data節(jié)點(diǎn)分離,限制角色

    • 主節(jié)點(diǎn)配置為:node.master: true,node.data: false

    • 從節(jié)點(diǎn)配置為:node.master: false,node.data: true ?

腦裂是由集群中的節(jié)點(diǎn)失聯(lián)導(dǎo)致的。

腦裂情況演示:?

例如一個(gè)集群中,主節(jié)點(diǎn)與其它節(jié)點(diǎn)失聯(lián):

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

此時(shí),node2和node3認(rèn)為node1宕機(jī)(但其實(shí)只是阻塞了),就會(huì)重新選主:

宕機(jī),即down機(jī)、死機(jī)。

指操作系統(tǒng)無(wú)法從一個(gè)嚴(yán)重系統(tǒng)錯(cuò)誤中恢復(fù)過(guò)來(lái),或系統(tǒng)硬件層面出問(wèn)題,以致系統(tǒng)長(zhǎng)時(shí)間無(wú)響應(yīng),而不得不重新啟動(dòng)計(jì)算機(jī)的現(xiàn)象。

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

當(dāng)node3當(dāng)選后,集群繼續(xù)對(duì)外提供服務(wù),node2和node3自成集群,node1自成集群,兩個(gè)集群數(shù)據(jù)不同步,出現(xiàn)數(shù)據(jù)差異。

當(dāng)網(wǎng)絡(luò)恢復(fù)后,因?yàn)榧褐杏袃蓚€(gè)master節(jié)點(diǎn),集群狀態(tài)的不一致,出現(xiàn)腦裂的情況:

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

解決腦裂?

解決腦裂的方案是,要求選票超過(guò) ( eligible節(jié)點(diǎn)數(shù)量 + 1 )/ 2 才能當(dāng)選為主,因此eligible節(jié)點(diǎn)數(shù)量最好是奇數(shù)。對(duì)應(yīng)配置項(xiàng)是discovery.zen.minimum_master_nodes,在es7.0以后,已經(jīng)成為默認(rèn)配置,因此一般不會(huì)發(fā)生腦裂問(wèn)題

例如:3個(gè)節(jié)點(diǎn)形成的集群,選票必須超過(guò) (3 + 1) / 2 ,也就是2票。node3得到node2和node3的選票,當(dāng)選為主。node1只有自己1票,沒(méi)有當(dāng)選。集群中依然只有1個(gè)主節(jié)點(diǎn),沒(méi)有出現(xiàn)腦裂。

4.2.3.小結(jié),四種節(jié)點(diǎn)類型

master eligible節(jié)點(diǎn)的作用是什么?

data節(jié)點(diǎn)的作用是什么?

coordinator節(jié)點(diǎn)的作用是什么?

4.3.集群分布式存儲(chǔ)

當(dāng)新增文檔時(shí),應(yīng)該保存到不同分片,保證數(shù)據(jù)均衡,那么coordinating node如何確定數(shù)據(jù)該存儲(chǔ)到哪個(gè)分片呢?

4.3.1.文檔存儲(chǔ)到分片測(cè)試

一個(gè)集群里有多個(gè)節(jié)點(diǎn),每個(gè)節(jié)點(diǎn)都是一個(gè)es實(shí)例,?每個(gè)節(jié)點(diǎn)保存了自己的分片和一個(gè)其他節(jié)點(diǎn)備份的分片。?

在9200端口的es插入三條數(shù)據(jù):

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

測(cè)試可以看到,三條數(shù)據(jù)分別在不同分片:

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

4.3.2.分片存儲(chǔ)原理

分布式新增如何確定分片??

elasticsearch會(huì)通過(guò)hash算法來(lái)計(jì)算文檔應(yīng)該存儲(chǔ)到哪個(gè)分片,跟文檔id和分片數(shù)量有關(guān):

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

說(shuō)明:

  • _routing默認(rèn)是文檔的id
  • 算法與分片數(shù)量有關(guān),因此索引庫(kù)一旦創(chuàng)建,分片數(shù)量不能修改!

新增文檔的流程如下:

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

解讀:

4.4.集群分布式查詢,協(xié)調(diào)節(jié)點(diǎn)的分散和聚集

elasticsearch的查詢分成兩個(gè)階段:

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

4.5.集群故障轉(zhuǎn)移

集群的master節(jié)點(diǎn)會(huì)監(jiān)控集群中的節(jié)點(diǎn)狀態(tài),如果發(fā)現(xiàn)有節(jié)點(diǎn)宕機(jī),會(huì)立即將宕機(jī)節(jié)點(diǎn)的分片數(shù)據(jù)遷移到其它節(jié)點(diǎn),確保數(shù)據(jù)安全,這個(gè)叫做故障轉(zhuǎn)移。

故障轉(zhuǎn)移流程演示:

1)例如一個(gè)集群結(jié)構(gòu)如圖:

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

現(xiàn)在,node1是主節(jié)點(diǎn),其它兩個(gè)節(jié)點(diǎn)是從節(jié)點(diǎn)。

2)突然,node1發(fā)生了故障:

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

宕機(jī)后的第一件事,需要重新選主,例如選中了node2:

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

node2成為主節(jié)點(diǎn)后,會(huì)檢測(cè)集群監(jiān)控狀態(tài),發(fā)現(xiàn):shard-1、shard-0沒(méi)有副本節(jié)點(diǎn)。因此需要將node1上的數(shù)據(jù)遷移到node2、node3:

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

實(shí)際演示:

現(xiàn)在有三個(gè)節(jié)點(diǎn),其中es01是主節(jié)點(diǎn)。

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

令es01宕機(jī)

docker-compose stop es01

此時(shí)es01節(jié)點(diǎn)上的1主分片和0副本分片沒(méi)了,主節(jié)點(diǎn)轉(zhuǎn)到es03,控制es01節(jié)點(diǎn)的數(shù)據(jù)遷移到es02和03。

故障轉(zhuǎn)移后,所有分片都有主分片和副本分片:

?ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

?再恢復(fù)es01,發(fā)現(xiàn)主節(jié)點(diǎn)es03遷移出兩個(gè)分片到es01:

docker-compose start es01

ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步

  • master節(jié)點(diǎn):對(duì)CPU要求高,但是內(nèi)存要求低
  • data節(jié)點(diǎn):對(duì)CPU和內(nèi)存要求都高
  • coordinating節(jié)點(diǎn):對(duì)網(wǎng)絡(luò)帶寬、CPU要求高
  • 參與集群選主
  • 主節(jié)點(diǎn)可以管理集群狀態(tài)、管理分片信息、處理創(chuàng)建和刪除索引庫(kù)的請(qǐng)求
  • 數(shù)據(jù)的CRUD
  • 路由請(qǐng)求到其它節(jié)點(diǎn)

  • 合并查詢到的結(jié)果,返回給用戶

  • 1)新增一個(gè)id=1的文檔
  • 2)對(duì)id做hash運(yùn)算,假如得到的是2,則應(yīng)該存儲(chǔ)到shard-2
  • 3)shard-2的主分片在node3節(jié)點(diǎn),將數(shù)據(jù)路由到node3
  • 4)保存文檔
  • 5)同步給shard-2的副本replica-2,在node2節(jié)點(diǎn)
  • 6)返回結(jié)果給coordinating-node節(jié)點(diǎn)
  • scatter phase:分散階段,coordinating node會(huì)把請(qǐng)求分發(fā)到每一個(gè)分片(只有data節(jié)點(diǎn)保存分片數(shù)據(jù))

  • gather phase:聚集階段,coordinating node匯總data node的搜索結(jié)果,并處理為最終結(jié)果集返回給用戶文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-415318.html

到了這里,關(guān)于ElasticSearch基礎(chǔ)3——聚合、補(bǔ)全、集群。黑馬旅游檢索高亮+自定義分詞器+自動(dòng)補(bǔ)全+前后端消息同步的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 微服務(wù)04 分布式搜索引擎 elasticsearch DSL數(shù)據(jù)聚合 自動(dòng)補(bǔ)全 數(shù)據(jù)同步 集群 微服務(wù)保護(hù) Sentinel

    微服務(wù)04 分布式搜索引擎 elasticsearch DSL數(shù)據(jù)聚合 自動(dòng)補(bǔ)全 數(shù)據(jù)同步 集群 微服務(wù)保護(hù) Sentinel

    聚合(aggregations)可以讓我們極其 方便的實(shí)現(xiàn)對(duì)數(shù)據(jù)的統(tǒng)計(jì)、分析、運(yùn)算 。例如: 什么品牌的手機(jī)最受歡迎? 這些手機(jī)的平均價(jià)格、最高價(jià)格、最低價(jià)格? 這些手機(jī)每月的銷(xiāo)售情況如何? 實(shí)現(xiàn)這些 統(tǒng)計(jì)功能的比數(shù)據(jù)庫(kù)的sql要方便的多,而且查詢速度非???,可以實(shí)現(xiàn)近

    2024年02月15日
    瀏覽(30)
  • ElasticSearch基礎(chǔ)1——索引和文檔。Kibana,RestClient操作索引和文檔+黑馬旅游ES庫(kù)導(dǎo)入

    ElasticSearch基礎(chǔ)1——索引和文檔。Kibana,RestClient操作索引和文檔+黑馬旅游ES庫(kù)導(dǎo)入

    導(dǎo)航: 【黑馬Java筆記+踩坑匯總】JavaSE+JavaWeb+SSM+SpringBoot+瑞吉外賣(mài)+SpringCloud/SpringCloudAlibaba+黑馬旅游+谷粒商城 黑馬旅游源碼:? https://wwmg.lanzouk.com/ikjTE135ybje 目錄 1.初識(shí)彈性搜索elasticsearch 1.1.了解ES 1.1.1.elasticsearch的作用 1.1.2.ELK彈性棧 1.1.3.elasticsearch和lucene 1.1.4.搜索引擎技術(shù)

    2024年02月01日
    瀏覽(50)
  • Elasticsearch實(shí)現(xiàn)檢索詞自動(dòng)補(bǔ)全(檢索詞補(bǔ)全,自動(dòng)糾錯(cuò),拼音補(bǔ)全,繁簡(jiǎn)轉(zhuǎn)換) 包含demo

    Elasticsearch實(shí)現(xiàn)檢索詞自動(dòng)補(bǔ)全(檢索詞補(bǔ)全,自動(dòng)糾錯(cuò),拼音補(bǔ)全,繁簡(jiǎn)轉(zhuǎn)換) 包含demo

    下面的請(qǐng)求定義了一個(gè)名為 “book” 的 Elasticsearch 索引,其中包含一個(gè) 具有 “text” 數(shù)據(jù)類型和 “standard” 分析器且名為 “title” 的字段。此字段用于處理書(shū)籍標(biāo)題的文本數(shù)據(jù)。定義了名為 “suggest” 的 “completion” 子字段,用于支持實(shí)時(shí)搜索建議的自動(dòng)補(bǔ)全功能。 增加測(cè)

    2024年02月07日
    瀏覽(18)
  • Elasticsearch --- 數(shù)據(jù)聚合、自動(dòng)補(bǔ)全

    Elasticsearch --- 數(shù)據(jù)聚合、自動(dòng)補(bǔ)全

    聚合(aggregations) 可以讓我們極其方便的實(shí)現(xiàn)對(duì)數(shù)據(jù)的統(tǒng)計(jì)、分析、運(yùn)算。例如: 什么品牌的手機(jī)最受歡迎? 這些手機(jī)的平均價(jià)格、最高價(jià)格、最低價(jià)格? 這些手機(jī)每月的銷(xiāo)售情況如何? 實(shí)現(xiàn)這些統(tǒng)計(jì)功能的比數(shù)據(jù)庫(kù)的sql要方便的多,而且查詢速度非???,可以實(shí)現(xiàn)近實(shí)

    2024年02月04日
    瀏覽(37)
  • 【Elasticsearch】黑馬旅游案例

    【Elasticsearch】黑馬旅游案例

    目錄 4.黑馬旅游案例 4.1.酒店搜索和分頁(yè) 4.1.1.需求分析 4.1.2.定義實(shí)體類 4.1.3.定義controller 4.1.4.實(shí)現(xiàn)搜索業(yè)務(wù) 4.2.酒店結(jié)果過(guò)濾 4.2.1.需求分析 4.2.2.修改實(shí)體類 4.2.3.修改搜索業(yè)務(wù) 4.3.我周邊的酒店 4.3.1.需求分析 4.3.2.修改實(shí)體類 4.3.3.距離排序API 4.3.4.添加距離排序 4.3.5.排序距離顯

    2024年02月16日
    瀏覽(19)
  • 【Elasticsearch】學(xué)習(xí)筆記-黑馬旅游網(wǎng)實(shí)踐

    【Elasticsearch】學(xué)習(xí)筆記-黑馬旅游網(wǎng)實(shí)踐

    在 HotelService 的 search 方法中,只有一個(gè)地方需要修改: requet.source().query( ... ) 其中的查詢條件。 在之前的業(yè)務(wù)中,只有 match 查詢,根據(jù)搜索,現(xiàn)在要添加條件過(guò)濾,包括: 品牌過(guò)濾:是 keyword 類型,用 term 查詢 星級(jí)過(guò)濾:是 keyword 類型,用 term 查詢 價(jià)格過(guò)濾:是數(shù)

    2024年04月16日
    瀏覽(17)
  • 微服務(wù)學(xué)習(xí)|elasticsearch:數(shù)據(jù)聚合、自動(dòng)補(bǔ)全、數(shù)據(jù)同步

    微服務(wù)學(xué)習(xí)|elasticsearch:數(shù)據(jù)聚合、自動(dòng)補(bǔ)全、數(shù)據(jù)同步

    聚合 (aggregations)可以實(shí)現(xiàn)對(duì)文檔數(shù)據(jù)的統(tǒng)計(jì)、分析、運(yùn)算。聚合常見(jiàn)的有三類: 桶(Bucket)聚合:用來(lái)對(duì)文檔做分組 TermAggregation:按照文檔字段值分組 Date Histogram:按照日期階梯分組,例如一周為一組,或者一月為一組 度量(Metric)聚合:用以計(jì)算一些值,比如: 最大值、最小值、平均

    2024年02月04日
    瀏覽(21)
  • ElasticSearch 數(shù)據(jù)聚合、自動(dòng)補(bǔ)全(自定義分詞器)、數(shù)據(jù)同步

    ElasticSearch 數(shù)據(jù)聚合、自動(dòng)補(bǔ)全(自定義分詞器)、數(shù)據(jù)同步

    官方文檔 = 聚合 https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations.html 聚合:對(duì)文檔信息的統(tǒng)計(jì)、分類、運(yùn)算。類似mysql sum、avg、count 桶(Bucket)聚合:用來(lái)對(duì)文檔做分組 TermAggregation:按照文檔字段值分組(相當(dāng)于mysql group by) Date Histogram:按照日期階梯分組,

    2024年02月12日
    瀏覽(25)
  • SpringCloud(十)——ElasticSearch簡(jiǎn)單了解(三)數(shù)據(jù)聚合和自動(dòng)補(bǔ)全

    SpringCloud(十)——ElasticSearch簡(jiǎn)單了解(三)數(shù)據(jù)聚合和自動(dòng)補(bǔ)全

    聚合 (aggregations)可以實(shí)現(xiàn)對(duì)文檔數(shù)據(jù)的統(tǒng)計(jì)、分析、運(yùn)算。 聚合常見(jiàn)的有三類: 桶(Bucket)聚合 :用來(lái)對(duì)文檔做分組 TermAggregation:按照文檔字段值分組 Date Histogram:按照日期階梯分組,例如一周為一組,或者一月為一組 度量(Metric)聚合 :用以計(jì)算一些值,比如:最大

    2024年02月09日
    瀏覽(23)
  • 黑馬旅游案例(包括搜索,分頁(yè),廣告置頂)中使用 elasticsearch 7.17.9 Java API

    黑馬旅游案例(包括搜索,分頁(yè),廣告置頂)中使用 elasticsearch 7.17.9 Java API

    引言 學(xué)習(xí)黑馬 SpringCloud 的 es 部分時(shí)發(fā)現(xiàn)老師用的是es的高級(jí)客戶端來(lái)操作es的,而高級(jí)客戶端已經(jīng)顯示棄用,上網(wǎng)搜索發(fā)現(xiàn)關(guān)于新的 Java client API 只有基礎(chǔ)的索引、文檔操作,沒(méi)有關(guān)于這種稍復(fù)雜案例的操作,于是自己琢磨整理了一份筆記,也為其他學(xué)習(xí)最新的 es 的小伙伴

    2024年02月11日
    瀏覽(27)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包