1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        1W字|40 圖|硬核 ES 實戰(zhàn)

        共 16278字,需瀏覽 33分鐘

         ·

        2021-04-18 20:57

        前言

        上篇我們講到了 Elasticsearch 全文檢索的原理《別只會搜日志了,求你懂點(diǎn)原理吧》,通過在本地搭建一套 ES 服務(wù),以多個案例來分析了 ES 的原理以及基礎(chǔ)使用。這次我們來講下 Spring Boot 中如何整合 ES,以及如何在 Spring Cloud 微服務(wù)項目中使用 ES 來實現(xiàn)全文檢索,來達(dá)到搜索題庫的功能。

        而且題庫的數(shù)據(jù)量是非常大的,題目的答案也是非常長的,通過 ES 正好可以解決 mysql 模糊搜索的低效性。

        通過本實戰(zhàn)您可以學(xué)到如下知識點(diǎn):

        • Spring Boot 如何整合 ES。
        • 微服務(wù)中 ES 的 API 使用。
        • 項目中如何使用 ES 來達(dá)到全文檢索。

        本篇主要內(nèi)容如下:

        主要內(nèi)容

        本文案例都是基于 PassJava 實戰(zhàn)項目來演示的。

        Github 地址:https://github.com/Jackson0714/PassJava-Platform

        為了讓大家更清晰地理解 PassJava 項目中 ES 是如何使用的,我畫了三個流程圖:

        • 第一步:創(chuàng)建 question 索引。

        首先定義 question 索引,然后在 ES 中創(chuàng)建索引。

        • 第二步:存 question 數(shù)據(jù)進(jìn) ES 。

        前端保存數(shù)據(jù)時,保存的 API 請求先經(jīng)過網(wǎng)關(guān),然后轉(zhuǎn)發(fā)到 passjava-question 微服務(wù),然后遠(yuǎn)程調(diào)用 passjava-search 微服務(wù),將數(shù)據(jù)保存進(jìn) ES 中。

        • 第三步:從 ES 中查數(shù)據(jù)。
          前端查詢數(shù)據(jù)時,先經(jīng)過網(wǎng)關(guān),然后將請求轉(zhuǎn)發(fā)給 passjava-search 微服務(wù),然后從 ES 中查詢數(shù)據(jù)。

        一、Elasticsearch 組件庫介紹

        在講解之前,我在這里再次提下全文檢索是什么:

        全文檢索: 指以全部文本信息作為檢索對象的一種信息檢索技術(shù)。而我們使用的數(shù)據(jù)庫,如 Mysql,MongoDB 對文本信息檢索能力特別是中文檢索并沒有 ES 強(qiáng)大。所以我們來看下 ES 在項目中是如何來代替 SQL 來工作的。

        我使用的 Elasticsearch 服務(wù)是 7.4.2 的版本,然后采用官方提供的 Elastiscsearch-Rest-Client 庫來操作 ES,而且官方庫的 API 上手簡單。

        該組件庫的官方文檔地址:

        https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high.html

        另外這個組件庫是支持多種語言的:

        支持多語言

        注意:Elasticsearch Clients 就是指如何用 API 操作 ES 服務(wù)的組件庫。

        可能有同學(xué)會提問,Elasticsearch 的組件庫中寫著 JavaScript API,是不是可以直接在前端訪問 ES 服務(wù)?可以是可以,但是會暴露 ES 服務(wù)的端口和 IP 地址,會非常不安全。所以我們還是用后端服務(wù)來訪問 ES 服務(wù)。

        我們這個項目是 Java 項目,自然就是用上面的兩種:Java Rest Client 或者 Java API。我們先看下 Java API,但是會發(fā)現(xiàn)已經(jīng)廢棄了。如下圖所示:

        Java API 已經(jīng)廢棄了

        所以我們只能用 Java REST Client 了。而它又分成兩種:高級和低級的。高級包含更多的功能,如果把高級比作MyBatis的話,那么低級就相當(dāng)于JDBC。所以我們用高級的 Client。

        高級和低級 Client

        二、整合檢索服務(wù)

        我們把檢索服務(wù)單獨(dú)作為一個服務(wù)。就稱作 passjava-search 模塊吧。

        1.1 添加搜索服務(wù)模塊

        • 創(chuàng)建 passjava-search 模塊。

        首先我們在 PassJava-Platform 模塊創(chuàng)建一個 搜索服務(wù)模塊 passjava-search。然后勾選 spring web 服務(wù)。如下圖所示。

        第一步:選擇 Spring Initializr,然后點(diǎn)擊 Next。

        選擇 Spring Initializr

        第二步:填寫模塊信息,然后點(diǎn)擊 Next。

        passjava-search 服務(wù)模塊

        第三步:選擇 Web->Spring Web 依賴,然后點(diǎn)擊 Next。

        1.2 配置 Maven 依賴

        • 參照 ES 官網(wǎng)配置。

        進(jìn)入到 ES 官方網(wǎng)站,可以看到有低級和高級的 Rest Client,我們選擇高階的(High Level Rest Client)。然后進(jìn)入到高階 Rest Client 的 Maven 倉庫。官網(wǎng)地址如下所示:

        https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.9/index.html
        Rest Client 官方文檔
        • 加上 Maven 依賴。

          對應(yīng)文件路徑:\passjava-search\pom.xml

        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <version>7.4.2</version>
        </dependency>
        • 配置 elasticsearch 的版本為7.4.2

          因加上 Maven 依賴后,elasticsearch 版本為 7.6.2,所以遇到這種版本不一致的情況時,需要手動改掉。

          對應(yīng)文件路徑:\passjava-search\pom.xml

        <properties>
        <elasticsearch.version>7.4.2</elasticsearch.version>
        </properties>

        刷新 Maven Project 后,可以看到引入的 elasticsearch 都是 7.4.2 版本了,如下圖所示:

        設(shè)置版本為 7.4.2
        • 引入 PassJava 的 Common 模塊依賴。

          Common 模塊是 PassJava 項目獨(dú)立的出來的公共模塊,引入了很多公共組件依賴,其他模塊引入 Common 模塊依賴后,就不需要單獨(dú)引入這些公共組件了,非常方便。

          對應(yīng)文件路徑:\passjava-search\pom.xml

         <dependency>
             <groupId>com.jackson0714.passjava</groupId>
             <artifactId>passjava-common</artifactId>
             <version>0.0.1-SNAPSHOT</version>
        </dependency>

        添加完依賴后,我們就可以將搜索服務(wù)注冊到 Nacos 注冊中心了。Nacos 注冊中心的用法在前面幾篇文章中也詳細(xì)講解過,這里需要注意的是要先啟動 Nacos 注冊中心,才能正常注冊 passjava-search 服務(wù)。

        1.3 注冊搜索服務(wù)到注冊中心

        修改配置文件:src/main/resources/application.properties。配置應(yīng)用程序名、注冊中心地址、注冊中心的命名中間。

        spring.application.name=passjava-search
        spring.cloud.nacos.config.server-addr=127.0.0.1:8848
        spring.cloud.nacos.config.namespace=passjava-search

        啟動類添加服務(wù)發(fā)現(xiàn)注解:@EnableDiscoveryClient。這樣 passjava-search 服務(wù)就可以被注冊中心發(fā)現(xiàn)了。

        因 Common 模塊依賴數(shù)據(jù)源,但 search 模塊不依賴數(shù)據(jù)源,所以 search 模塊需要移除數(shù)據(jù)源依賴:

        exclude = DataSourceAutoConfiguration.class

        以上的兩個注解如下所示:

        @EnableDiscoveryClient
        @SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
        public class PassjavaSearchApplication 
        {
            public static void main(String[] args) {
                SpringApplication.run(PassjavaSearchApplication.classargs);
            }
        }

        接下來我們添加一個 ES 服務(wù)的專屬配置類,主要目的是自動加載一個 ES Client 來供后續(xù) ES API 使用,不用每次都 new 一個 ES Client。

        1.4 添加 ES 配置類

        配置類:PassJavaElasticsearchConfig.java

        核心方法就是 RestClient.builder 方法,設(shè)置好 ES 服務(wù)的 IP 地址、端口號、傳輸協(xié)議就可以了。最后自動加載了 RestHighLevelClient。

        package com.jackson0714.passjava.search.config;

        import org.apache.http.HttpHost;
        import org.elasticsearch.client.RestClient;
        import org.elasticsearch.client.RestHighLevelClient;
        import org.springframework.context.annotation.Bean;
        import org.springframework.context.annotation.Configuration;

        /**
         * @Author: 公眾號 | 悟空聊架構(gòu)
         * @Date: 2020/10/8 17:02
         * @Site: www.passjava.cn
         * @Github: https://github.com/Jackson0714/PassJava-Platform
         */

        @Configuration
        public class PassJavaElasticsearchConfig {

            @Bean
            // 給容器注冊一個 RestHighLevelClient,用來操作 ES
            // 參考官方文檔:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.9/java-rest-high-getting-started-initialization.html
            public RestHighLevelClient restHighLevelClient() {
                return new RestHighLevelClient(
                        RestClient.builder(
                                new HttpHost("192.168.56.10"9200"http")));
            }
        }

        接下來我們測試下 ES Client 是否自動加載成功。

        1.5 測試 ES Client 自動加載

        在測試類 PassjavaSearchApplicationTests 中編寫測試方法,打印出自動加載的 ES Client。期望結(jié)果是一個 RestHighLevelClient 對象。

        package com.jackson0714.passjava.search;

        import org.elasticsearch.client.RestHighLevelClient;
        import org.junit.jupiter.api.Test;
        import org.springframework.beans.factory.annotation.Autowired;
        import org.springframework.beans.factory.annotation.Qualifier;
        import org.springframework.boot.test.context.SpringBootTest;

        @SpringBootTest
        class PassjavaSearchApplicationTests {

            @Qualifier("restHighLevelClient")
            @Autowired
            private RestHighLevelClient client;

            @Test
            public void contextLoads() {
                System.out.println(client);
            }
        }

        運(yùn)行結(jié)果如下所示,打印出了 RestHighLevelClient。說明自定義的 ES Client 自動裝載成功。

        ES 測試結(jié)果

        1.6 測試 ES 簡單插入數(shù)據(jù)

        測試方法 testIndexData,省略 User 類。users 索引在我的 ES 中是沒有記錄的,所以期望結(jié)果是 ES 中新增了一條 users 數(shù)據(jù)。

        /**
         * 測試存儲數(shù)據(jù)到 ES。
         * */

        @Test
        public void testIndexData() throws IOException {
            IndexRequest request = new IndexRequest("users");
            request.id("1"); // 文檔的 id
            
            //構(gòu)造 User 對象
            User user = new User();
            user.setUserName("PassJava");
            user.setAge("18");
            user.setGender("Man");
            
            //User 對象轉(zhuǎn)為 JSON 數(shù)據(jù)
            String jsonString = JSON.toJSONString(user);
            
            // JSON 數(shù)據(jù)放入 request 中
            request.source(jsonString, XContentType.JSON);

            // 執(zhí)行插入操作
            IndexResponse response = client.index(request, RequestOptions.DEFAULT);

            System.out.println(response);
        }

        執(zhí)行 test 方法,我們可以看到控制臺輸出以下結(jié)果,說明數(shù)據(jù)插入到 ES 成功。另外需要注意的是結(jié)果中的 result 字段為 updated,是因為我本地為了截圖,多執(zhí)行了幾次插入操作,但因為 id = 1,所以做的都是 updated 操作,而不是 created 操作。

        控制臺輸出結(jié)果

        我們再來到 ES 中看下 users 索引中數(shù)據(jù)。查詢 users 索引:

        GET users/_search

        結(jié)果如下所示:

        查詢 users 索引結(jié)果

        可以從圖中看到有一條記錄被查詢出來,查詢出來的數(shù)據(jù)的 _id = 1,和插入的文檔 id 一致。另外幾個字段的值也是一致的。說明插入的數(shù)據(jù)沒有問題。

        "age" : "18",
        "gender" : "Man",
        "userName" : "PassJava"

        1.7 測試 ES 查詢復(fù)雜語句

        示例:搜索 bank 索引,address 字段中包含 big 的所有人的年齡分布 ( 前 10 條 ) 以及平均年齡,以及平均薪資。

        1.7.1 構(gòu)造檢索條件

        我們可以參照官方文檔給出的示例來創(chuàng)建一個 SearchRequest 對象,指定要查詢的索引為 bank,然后創(chuàng)建一個 SearchSourceBuilder 來組裝查詢條件??偣灿腥N條件需要組裝:

        • address 中包含 road 的所有人。
        • 按照年齡分布進(jìn)行聚合。
        • 計算平均薪資。

        代碼如下所示,需要源碼請到我的 Github/PassJava 上下載。

        查詢復(fù)雜語句示例

        將打印出來的檢索參數(shù)復(fù)制出來,然后放到 JSON 格式化工具中格式化一下,再粘貼到 ES 控制臺執(zhí)行,發(fā)現(xiàn)執(zhí)行結(jié)果是正確的。

        打印出檢索參數(shù)

        用在線工具格式化 JSON 字符串,結(jié)果如下所示:

        然后我們?nèi)サ羝渲械囊恍┠J(rèn)參數(shù),最后簡化后的檢索參數(shù)放到 Kibana 中執(zhí)行。

        Kibana Dev Tools 控制臺中執(zhí)行檢索語句如下圖所示,檢索結(jié)果如下圖所示:

        控制臺中執(zhí)行檢索語句

        找到總記錄數(shù):29 條。

        第一條命中記錄的詳情如下:

        平均 balance:13136。

        平均年齡:26。

        地址中包含 Road 的:263 Aviation Road。

        和 IDEA 中執(zhí)行的測試結(jié)果一致,說明復(fù)雜檢索的功能已經(jīng)成功實現(xiàn)。

        17.2 獲取命中記錄的詳情

        而獲取命中記錄的詳情數(shù)據(jù),則需要通過兩次 getHists() 方法拿到,如下所示:

        // 3.1)獲取查到的數(shù)據(jù)。
        SearchHits hits = response.getHits();
        // 3.2)獲取真正命中的結(jié)果
        SearchHit[] searchHits = hits.getHits();

        我們可以通過遍歷 searchHits 的方式打印出所有命中結(jié)果的詳情。

        // 3.3)、遍歷命中結(jié)果
        for (SearchHit hit: searchHits) {
            String hitStr = hit.getSourceAsString();
            BankMember bankMember = JSON.parseObject(hitStr, BankMember.class);
        }

        拿到每條記錄的 hitStr 是個 JSON 數(shù)據(jù),如下所示:

        {
         "account_number"431,
         "balance"13136,
         "firstname""Laurie",
         "lastname""Shaw",
         "age"26,
         "gender""F",
         "address""263 Aviation Road",
         "employer""Zillanet",
         "email""[email protected]",
         "city""Harmon",
         "state""WV"
        }

        而 BankMember 是根據(jù)返回的結(jié)果詳情定義的的 JavaBean。可以通過工具自動生成。在線生成 JavaBean 的網(wǎng)站如下:

        https://www.bejson.com/json2javapojo/new/

        把這個 JavaBean 加到 PassjavaSearchApplicationTests 類中:

        @ToString
        @Data
        static class BankMember {
            private int account_number;
            private int balance;
            private String firstname;
            private String lastname;
            private int age;
            private String gender;
            private String address;
            private String employer;
            private String email;
            private String city;
            private String state;
        }

        然后將 bankMember 打印出來:

        System.out.println(bankMember);
        bankMember

        得到的結(jié)果確實是我們封裝的 BankMember 對象,而且里面的屬性值也都拿到了。

        1.7.3 獲取年齡分布聚合信息

        ES 返回的 response 中,年齡分布的數(shù)據(jù)是按照 ES 的格式返回的,如果想按照我們自己的格式來返回,就需要將 response 進(jìn)行處理。

        如下圖所示,這個是查詢到的年齡分布結(jié)果,我們需要將其中某些字段取出來,比如 buckets,它代表了分布在 21 歲的有 4 個。

        ES 返回的年齡分布信息

        下面是代碼實現(xiàn):

        Aggregations aggregations = response.getAggregations();
        Terms ageAgg1 = aggregations.get("ageAgg");
        for (Terms.Bucket bucket : ageAgg1.getBuckets()) {
            String keyAsString = bucket.getKeyAsString();
            System.out.println("用戶年齡: " + keyAsString + " 人數(shù):" + bucket.getDocCount());
        }

        最后打印的結(jié)果如下,21 歲的有 4 人,26 歲的有 4 人,等等。

        打印結(jié)果:用戶年齡分布

        1.7.4 獲取平均薪資聚合信息

        現(xiàn)在來看看平均薪資如何按照所需的格式返回,ES 返回的結(jié)果如下圖所示,我們需要獲取 balanceAvg 字段的 value 值。

        ES 返回的平均薪資信息

        代碼實現(xiàn):

        Avg balanceAvg1 = aggregations.get("balanceAvg");
        System.out.println("平均薪資:" + balanceAvg1.getValue());

        打印結(jié)果如下,平均薪資 28578 元。

        打印結(jié)果:平均薪資

        三、實戰(zhàn):同步 ES 數(shù)據(jù)

        3.1 定義檢索模型

        PassJava 這個項目可以用來配置題庫,如果我們想通過關(guān)鍵字來搜索題庫,該怎么做呢?

        類似于百度搜索,輸入幾個關(guān)鍵字就可以搜到關(guān)聯(lián)的結(jié)果,我們這個功能也是類似,通過 Elasticsearch 做檢索引擎,后臺管理界面和小程序作為搜索入口,只需要在小程序上輸入關(guān)鍵字,就可以檢索相關(guān)的題目和答案。

        首先我們需要把題目和答案保存到 ES 中,在存之前,第一步是定義索引的模型,如下所示,模型中有 titleanswer 字段,表示題目和答案。

        "id": {
            "type""long"
        },
        "title": {
            "type""text",
            "analyzer""ik_smart"
        },
        "answer": {
            "type""text",
            "analyzer""ik_smart"
        },
        "typeName": {
            "type""keyword"
        }

        3.2 在 ES 中創(chuàng)建索引

        上面我們已經(jīng)定義了索引結(jié)構(gòu),接著就是在 ES 中創(chuàng)建索引。

        在 Kibana 控制臺中執(zhí)行以下語句:

        PUT question
        {
         "mappings" : {
             "properties": {
             "id": {
              "type""long"
             },
             "title": {
              "type""text",
              "analyzer""ik_smart"
             },
             "answer": {
              "type""text",
              "analyzer""ik_smart"
             },
             "typeName": {
              "type""keyword"
             }
          }
          }
        }

        執(zhí)行結(jié)果如下所示:

        創(chuàng)建 question 索引

        我們可以通過以下命令來查看 question 索引是否在 ES 中:

        GET _cat/indices

        執(zhí)行結(jié)果如下圖所示:

        查看 ES 中所有的索引

        3.3 定義 ES model

        上面我們定義 ES 的索引,接著就是定義索引對應(yīng)的模型,將數(shù)據(jù)存到這個模型中,然后再存到 ES 中。

        ES 模型如下,共四個字段:id、title、answer、typeName。和 ES 索引是相互對應(yīng)的。

        @Data
        public class QuestionEsModel {
            private Long id;
            private String title;
            private String answer;
            private String typeName;
        }

        3.4 觸發(fā)保存的時機(jī)

        當(dāng)我們在后臺創(chuàng)建題目或保存題目時,先將數(shù)據(jù)保存到 mysql 數(shù)據(jù)庫,然后再保存到 ES 中。

        如下圖所示,在管理后臺創(chuàng)建題目時,觸發(fā)保存數(shù)據(jù)到 ES 。


        第一步,保存數(shù)據(jù)到 mysql 中,項目中已經(jīng)包含此功能,就不再講解了,直接進(jìn)入第二步:保存數(shù)據(jù)到 ES 中。

        而保存數(shù)據(jù)到 ES 中,需要將數(shù)據(jù)組裝成 ES 索引對應(yīng)的數(shù)據(jù),所以我用了一個 ES model,先將數(shù)據(jù)保存到 ES model 中。

        3.5 用 model 來組裝數(shù)據(jù)

        這里的關(guān)鍵代碼時 copyProperties,可以將 question 對象的數(shù)據(jù)取出,然后賦值到 ES model 中。不過 ES model 中還有些字段是 question 中沒有的,所以需要單獨(dú)拎出來賦值,比如 typeName 字段,question 對象中沒有這個字段,它對應(yīng)的字段是 question.type,所以我們把 type 取出來賦值到 ES model 的 typeName 字段上。如下圖所示:

        用 model 來組裝數(shù)據(jù)

        3.6 保存數(shù)據(jù)到 ES

        我在 passjava-search 微服務(wù)中寫了一個保存題目的 api 用來保存數(shù)據(jù)到 ES 中。

        保存數(shù)據(jù)到 ES

        然后在 passjava-question 微服務(wù)中調(diào)用 search 微服務(wù)的保存 ES 的方法就可以了。

        // 調(diào)用 passjava-search 服務(wù),將數(shù)據(jù)發(fā)送到 ES 中保存。
        searchFeignService.saveQuestion(esModel);

        3.7 檢驗 ES 中是否創(chuàng)建成功

        我們可以通過 kibana 的控制臺來查看 question 索引中的文檔。通過以下命令來查看:

        GET question/_search

        執(zhí)行結(jié)果如下圖所示,有一條記錄:

        另外大家有沒有疑問:可以重復(fù)更新題目嗎?

        答案是可以的,保存到 ES 的數(shù)據(jù)是冪等的,因為保存的時候帶了一個類似數(shù)據(jù)庫主鍵的 id。

        四、實戰(zhàn):查詢 ES 數(shù)據(jù)

        我們已經(jīng)將數(shù)據(jù)同步到了 ES 中,現(xiàn)在就是前端怎么去查詢 ES 數(shù)據(jù)中,這里我們還是使用 Postman 來模擬前端查詢請求。

        4.1 定義請求參數(shù)

        請求參數(shù)我定義了三個:

        • keyword:用來匹配問題或者答案。
        • id:用來匹配題目 id。
        • pageNum:用來分頁查詢數(shù)據(jù)。

        這里我將這三個參數(shù)定義為一個類:

        @Data
        public class SearchParam {
            private String keyword; // 全文匹配的關(guān)鍵字
            private String id; // 題目 id
            private Integer pageNum; // 查詢第幾頁數(shù)據(jù)
        }

        4.2 定義返回參數(shù)

        返回的 response 我也定義了四個字段:

        • questionList:查詢到的題目列表。
        • pageNum:第幾頁數(shù)據(jù)。
        • total:查詢到的總條數(shù)。
        • totalPages:總頁數(shù)。

        定義的類如下所示:

        @Data
        public class SearchQuestionResponse {
            private List<QuestionEsModel> questionList; // 題目列表
            private Integer pageNum; // 查詢第幾頁數(shù)據(jù)
            private Long total; // 總條數(shù)
            private Integer totalPages; // 總頁數(shù)
        }

        4.3 組裝 ES 查詢參數(shù)

        調(diào)用 ES 的查詢 API 時,需要構(gòu)建查詢參數(shù)。

        組裝查詢參數(shù)的核心代碼如下所示:

        組裝查詢參數(shù)
        • 第一步:創(chuàng)建檢索請求。

        • 第二步:設(shè)置哪些字段需要模糊匹配。這里有三個字段:title,answer,typeName。

        • 第三步:設(shè)置如何分頁。這里分頁大小是 5 個。

        • 第四步:調(diào)用查詢 api。

        4.4 格式化 ES 返回結(jié)果

        ES 返回的數(shù)據(jù)是 ES 定義的格式,真正的數(shù)據(jù)被嵌套在 ES 的 response 中,所以需要格式化返回的數(shù)據(jù)。

        核心代碼如下圖所示:

        格式化 ES 返回結(jié)果
        • 第一步:獲取查到的數(shù)據(jù)。
        • 第二步:獲取真正命中的結(jié)果。
        • 第三步:格式化返回的數(shù)據(jù)。
        • 第四步:組裝分頁參數(shù)。

        4.5 測試 ES 查詢

        4.5.1 實驗一:測試 title 匹配

        我們現(xiàn)在想要驗證 title 字段是否能匹配到,傳的請求參數(shù) keyword = 111,匹配到了 title = 111 的數(shù)據(jù),且只有一條。頁碼 pageNum 我傳的 1,表示返回第一頁數(shù)據(jù)。如下圖所示:

        測試匹配 title

        4.5.2 實驗二:測試 answer 匹配

        我們現(xiàn)在想要驗證 answer 字段是否能匹配到,傳的請求參數(shù) keyword = 測試答案,匹配到了 title =  測試答案的數(shù)據(jù),且只有一條,說明查詢成功。如下圖所示:

        測試匹配 answer

        4.5.2 實驗三:測試 id 匹配

        我們現(xiàn)在想要匹配題目 id 的話,需要傳請求參數(shù) id,而且 id 是精確匹配。另外 id 和 keyword 是取并集,所以不能傳 keyword 字段。

        請求參數(shù) id = 5,返回結(jié)果也是 id =5 的數(shù)據(jù),說明查詢成功。如下圖所示:

        測試 id 匹配

        五、總結(jié)

        本文通過我的開源項目 passjava 來講解 ES 的整合,ES 的 API 使用以及測試。非常詳細(xì)地講解了每一步該如何做,相信通過閱讀本篇后,再加上自己的實踐,一定能掌握前后端該如何使用 ES 來達(dá)到高效搜索的目的。

        當(dāng)然,ES API 還有很多功能未在本文實踐,有興趣的同學(xué)可以到 ES 官網(wǎng)進(jìn)行查閱和學(xué)習(xí)。

        再次強(qiáng)調(diào):本文的代碼都是辛苦調(diào)試出來的,請不要忘記點(diǎn)贊和轉(zhuǎn)發(fā)哦~

        推薦?? :1049天,100K!簡單復(fù)盤!

        推薦?? :Github掘金計劃:Github上的一些優(yōu)質(zhì)項目搜羅

        我是 Guide哥,擁抱開源,喜歡烹飪。Github 接近 10w 點(diǎn)贊的開源項目 JavaGuide 的作者。未來幾年,希望持續(xù)完善 JavaGuide,爭取能夠幫助更多學(xué)習(xí) Java 的小伙伴!共勉!凎!點(diǎn)擊查看我的2020年工作匯報!
        原創(chuàng)不易,歡迎點(diǎn)贊分享。咱們下期再會!
        瀏覽 43
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            太粗大深好疼快拔出去软件 | 免费在线观看黄视频 | 操逼短视频 | 《色戒》无删减完整版在线播放 | 女大扒开腿秘 让人桶爽 | 尤物193 | 日本68xxxxxxxxx21 | 久久久久久三级 | 下面张开腿对着镜子灌酒h | 亚洲免费观看高清完整 |