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>

        該怎么學(xué)elasticsearch?看這篇就夠啦~

        共 26761字,需瀏覽 54分鐘

         ·

        2021-05-19 12:35


        來源 | Java技術(shù)迷(ID:JavaFans1024

        安裝ElasticSearch

        首先來到官網(wǎng)下載ElasticSearch:https://www.elastic.co/cn/elasticsearch/


        ' 點(diǎn)擊按鈕進(jìn)行下載:

        我們以Windows版本為例,下載完成后解壓出來,然后執(zhí)行bin目錄下的 elasticsearch.bat 文件:


        等待啟動完成后,訪問http://localhost:9200/:


        看到此界面則說明ElasticSearch啟動成功了。

        相關(guān)概念

        在正式學(xué)習(xí)ElasticSearch之前,我們先來了解一下ElasticSearch。

        Elasticsearch是一個(gè)基于Lucene的搜索服務(wù)器。它提供了一個(gè)分布式多用戶能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java語言開發(fā)的,并作為Apache許可條款下的開放源碼發(fā)布,是一種流行的企業(yè)級搜索引擎。

        在ElasticSearch中有四個(gè)相關(guān)的概念:

        1. 索引
        2. 類型
        3. 文檔
        4. 字段

        我們可以將其類比到關(guān)系型數(shù)據(jù)庫中,索引就是一個(gè)數(shù)據(jù)庫,類型就是一張數(shù)據(jù)表,而文檔就是數(shù)據(jù)表中的一行,字段就是數(shù)據(jù)表中的一列,如下圖:



        ElasticSearch通常用于網(wǎng)站的全文檢索,這意味著ElasticSearch將承擔(dān)著整個(gè)系統(tǒng)最大搜索量的搜索業(yè)務(wù),想象一下在淘寶搜索入口上搜索一個(gè)手機(jī),系統(tǒng)背后需要經(jīng)歷多么大的數(shù)據(jù)量查詢。然而在如此大數(shù)據(jù)量的情況下,ElasticSearch仍然能夠非常出色的完成任務(wù),它是如何做到的呢?

        我們先來看一張關(guān)系型數(shù)據(jù)庫中的數(shù)據(jù)表:

        +----+------------+
        | id | name       |
        +----+------------+
        |  1 | zhang san  |
        |  2 | zhang san2 |
        |  3 | zhang san3 |
        |  4 | li si      |
        +----+------------+

        假設(shè)這張數(shù)據(jù)表的數(shù)據(jù)量非常龐大,若是想進(jìn)行模糊查詢,查詢姓 zhang 的用戶信息,那么它的效率一定是很低的,因?yàn)樗枰獜牡谝粭l數(shù)據(jù)開始遍歷到最后一條數(shù)據(jù)。來看看ElasticSearch是如何做的,它采用的是一種叫 倒排索引 的方式,即:在插入數(shù)據(jù)的時(shí)候就建立了一張關(guān)鍵字與id的對應(yīng)表:

        +---------+-------+
        | keyword | id    |
        +----+------------+
        |  zhang  | 1,2,3 |
        |   san   | 1,2,3 |
        |    li   |   4   |
        |    si   |   4   |
        +---------+-------+

        它會將名字中的關(guān)鍵字提取出來,并記錄當(dāng)前id擁有哪些關(guān)鍵字,將其存放起來,此時(shí)我們查詢姓 zhang 的用戶信息時(shí),我們將直接得到姓 zhang 的用戶id為 1、2、3 ,然后通過id找到用戶信息即可,查詢效率大幅提升了。

        需要注意的是,從ElasticSearch7.X版本開始,Type的概念已經(jīng)被移除了。

        索引

        接下來我們就來看看ElasticSearch中索引的具體操作,因?yàn)樗腔赗ESTful web接口的,所以我們使用Postman進(jìn)行測試。

        創(chuàng)建索引

        訪問路徑為 http://localhost:9200/user,請求方式一定要選擇PUT,了解RESTful接口的同學(xué)都知道,接口的請求方式?jīng)Q定了這次請求的行為,當(dāng)出現(xiàn)底部的響應(yīng)內(nèi)容時(shí),說明索引創(chuàng)建成功了。

        查詢索引

        查詢索引非常簡單,我們只需要修改剛才的請求方式為GET即可:


        響應(yīng)的內(nèi)容是剛剛創(chuàng)建的索引信息,若是想查詢ElasticSearch中的所有索引,則訪問 _cat :

        刪除索引

        相信你已經(jīng)知道該如何刪除索引了吧,沒錯(cuò),只需要將請求方式修改為DELETE即可:

        文檔

        我們再來看看文檔的相關(guān)操作,文檔對應(yīng)關(guān)系型數(shù)據(jù)庫中的數(shù)據(jù)行。

        創(chuàng)建文檔

        創(chuàng)建文檔的方式也非常簡單:


        首先在訪問路徑上添加 /_doc ,其次修改請求方式為POST,最后不要忘記添加請求體參數(shù),它將作為我們的文檔數(shù)據(jù)。需要注意的是,創(chuàng)建索引使用的是PUT請求,而創(chuàng)建文檔使用的是POST請求,千萬不能搞混了,實(shí)在記不清的話,你可以這樣理解,當(dāng)我們在創(chuàng)建文檔時(shí),響應(yīng)內(nèi)容中有一項(xiàng) _id 參數(shù),而每次請求這個(gè) _id 都是會變化的,這就說明該接口是不符合冪等性的。

        冪等性就是指用戶對于同一操作發(fā)起的一次請求或者多次請求的結(jié)果是一致的,不會因?yàn)槎啻吸c(diǎn)擊而產(chǎn)生了副作用。

        而PUT方式要求接口必須符合冪等性,所以我們在創(chuàng)建文檔時(shí)就不能選擇使用PUT方式,這樣記憶是不是會更好呢。

        在創(chuàng)建文檔時(shí)我們可以通過url指定文檔的id:


        因?yàn)榇藭r(shí)的id是由你自己指定的,所以每次發(fā)送請求得到的響應(yīng)結(jié)果其實(shí)是一樣的,符合冪等性,因此,這種指定id創(chuàng)建文檔的方式也可以使用PUT請求:

        查詢文檔

        通過GET請求方式即可查詢文檔:


        使用 _search 即可查詢所有ElasticSearch中的所有文檔數(shù)據(jù):

        更新文檔

        更新文檔分為兩種方式:

        1. 全量更新
        2. 局部更新

        其中全量更新指的是將文檔中的數(shù)據(jù)全部進(jìn)行更新,由于是全部更新,每次請求響應(yīng)的內(nèi)容是一致的,符合冪等性,所以可以使用PUT請求(當(dāng)然了,POST請求一定也是可以的):


        而對于局部更新,因?yàn)槊看胃碌膬?nèi)容可能不同,導(dǎo)致響應(yīng)的結(jié)果也不同,它就不符合接口的冪等性,所以它只能使用POST請求進(jìn)行更新:


        此時(shí)我們的url需要進(jìn)行修改,使用 _update 來指定此次操作為更新操作(對應(yīng)的還有 _create 操作,只不過它與 _doc 功能相同,都是創(chuàng)建索引),而且請求體參數(shù)也發(fā)生了變化,需要更新的屬性值需要寫在 doc 屬性中。

        刪除文檔

        只需將請求方式設(shè)置為DELETE即可完成對文檔的刪除:

        高級查詢

        作為全文檢索工具,ElasticSearch在查詢方面具有無與倫比的效率,為此,我們再來看看ElasticSearch中關(guān)于查詢的一些高級內(nèi)容。

        條件查詢

        要想實(shí)現(xiàn)條件查詢,我們就需要將查詢條件拼接到url中:


        我們知道, _search 可以查詢ElasticSearch中的所有文檔數(shù)據(jù),通過 q 參數(shù)即可傳入查詢條件。

        使用url傳遞參數(shù)有諸多弊端,編寫麻煩而且容易出現(xiàn)亂碼問題,所以我們可以將查詢條件作為請求體參數(shù)進(jìn)行傳遞:


        請求體參數(shù)中, query 表示這是一個(gè)查詢條件, match 指定的是查詢模式,為匹配查詢,匹配內(nèi)容為 name 等于 zhangsan 。

        ElasticSearch當(dāng)然也支持分頁查詢:


        其中 from 用于指定頁碼, size 指定每頁記錄數(shù),這里則表示按每頁兩條記錄數(shù)進(jìn)行分頁,并返回第一頁的文檔數(shù)據(jù)。請求參數(shù)中指定 _source 能夠指定響應(yīng)內(nèi)容中文檔的數(shù)據(jù),比如:

        {
          "query":{
            "match":{
              "name":"zhangsan"
            }
          },
          "from":0,
          "size":2,
          "_source":["name"]
        }

        它表示在分頁查詢的基礎(chǔ)上只顯示 name 屬性值。若是想實(shí)現(xiàn)查詢時(shí)排序,則只需在請求體參數(shù)中添加一個(gè) sort 屬性:

        {
          "query":{
            "match":{
              "name":"zhangsan"
            }
          },
          "from":0,
          "size":2,
          "_source":["name"],
          "sort":{
            "age":{
              "order":"asc"
            }
          }
        }

        它表示按照年齡進(jìn)行升序。

        多條件查詢

        若是想實(shí)現(xiàn)多條件查詢,則需要進(jìn)一步封裝請求體參數(shù),比如查詢 name 為 zhangsan 且 age 等于 20 的用戶信息:


        請求體參數(shù)為:

        {
          "query":{
            "bool":{
              "must":[
                {
                  "match":{
                    "name":"zhangsan"
                  }
                },
                {
                  "match":{
                    "age":"20"
                  }
                }
              ]
            }
          }
        }

        其中 query 表示查詢,不必多說, bool 表示查詢條件,之后就是 must 了,它表示must中的內(nèi)容一定要成立,must中可以填寫多個(gè)查詢條件,match 表示匹配,匹配內(nèi)容為 name 等于 zhangsan , age 等于 20 。

        若是想實(shí)現(xiàn)查詢 name 為 zhangsan 或者 lisi 的用戶,則需要將 must 替換為 should :

        {
          "query":{
            "bool":{
              "should":[
                {
                  "match":{
                    "name":"zhangsan"
                  }
                },
                {
                  "match":{
                    "name":"lisi"

                  }
                }
              ]
            }
          }
        }

        若是想查詢年齡在20~30之間的用戶信息,則我們需要借助 filter 屬性:

        {
          "query":{
            "bool":{
              "filter":{
                "range":{
                  "age":{
                    "gt":20,
                    "lt":30
                  }
                }
              }
            }
          }
        }

        全文檢索


        當(dāng)我們在檢索某個(gè)關(guān)鍵字的時(shí)候,ElasticSearch仍然能夠準(zhǔn)備查詢到相關(guān)信息,這是因?yàn)镋lasticSearch會將文字分詞并與文檔id作對應(yīng)形成倒排索引,相關(guān)內(nèi)容我們在前面就已經(jīng)接觸到了,這就是ElasticSearch的全文檢索功能。當(dāng)我們的姓名是兩個(gè)漢字時(shí):

        {
          "query":{
            "match":{
              "name":"張李"
            }
          }
        }

        ElasticSearch仍然會將其分為 張 和 李 兩個(gè)字,并分別做匹配,若是我們就想查詢名字叫 張李 的用戶,那么就不能使用 match 匹配了,而是使用 match_phrase :

        {
          "query":{
            "match_phrase":{
              "name":"張李"
            }
          }
        }

        它表示的是完全匹配,即:匹配的內(nèi)容必須和屬性值完全一致。我們還可以讓匹配的內(nèi)容高亮顯示:

        {
          "query":{
            "match_phrase":{
              "name":"張三"
            }
          },
          "highlight":{
            "fields":{
              "name":{}
            }
          }
        }

        使用 highlight 指定需要高亮顯示的屬性。

        聚合查詢

        若是想對查詢的數(shù)據(jù)進(jìn)行分組管理,在ElasticSearch中稱為聚合操作,比如:

        {
          "aggs":{
            "age_group":{
              "terms":{
                "field":"age"
              }
            }
          }
        }

        aggs 表示這是一次聚合操作, age_group 是統(tǒng)計(jì)結(jié)果的名稱,可以隨意指定, terms 表示以哪個(gè)屬性進(jìn)行分組。分組后的結(jié)果:


        它將顯示出每個(gè)年齡的用戶數(shù)量。

        求每個(gè)用戶的年齡平均值:

        {
          "aggs":{
            "age_avg":{
              "avg":{
                "field":"age"
              }
            }
          }
        }

        結(jié)果:

        ....
        "aggregations": {
          "age_avg": {
            "value"23.0
          }
        }
        ....

        Java項(xiàng)目中如何操作ElasticSearch

        下面我們來看看在Java項(xiàng)目中該如何使用ElasticSearch以及相關(guān)操作。首先創(chuàng)建一個(gè)普通的Maven項(xiàng)目,并引入依賴:

        <dependencies>
          <dependency>
            <groupId>org.elasticsearch</groupId>
            <artifactId>elasticsearch</artifactId>
            <version>7.8.0</version>
          </dependency>
          <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <version>7.8.0</version>
          </dependency>
          <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.8.2</version>
          </dependency>
          <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.8.2</version>
          </dependency>
          <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.9.9</version>
          </dependency>
          <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
          </dependency>
        </dependencies>

        在正式操作之前,我們先在Linux環(huán)境安裝一下ElasticSearch,這里推薦使用Docker進(jìn)行環(huán)境搭建,首先拉取ElasticSearch的鏡像:

        docker pull elasticsearch:7.4.2

        然后創(chuàng)建兩個(gè)文件夾

        mkdir -p /mydata/elasticsearch/config
        mkdir -p /mydata/elasticsearch/data

        它們將分別用于存放ElasticSearch的配置文件和數(shù)據(jù)文件,然后修改一下文件夾權(quán)限:

        chmod 777 /mydata/elasticsearch/data/

        這樣就可以啟動ElasticSearch了:

        docker run --name elasticsearch -p 9200:9200 -p 9300:9300 \
        -e "discovery.type=single-node" \
        -e ES_JAVA_OPTS="-Xms64m -Xmx128m" \
        -v /mydata/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \
        -v /mydata/elasticsearch/data:/usr/share/elasticsearch/data \
        -v /mydata/elasticsearch/plugins:/usr/share/elasticsearch/plugins \
        -d elasticsearch:7.4.2

        啟動完成后,同樣測試一下:



        接下來我們就可以在Java程序中嘗試創(chuàng)建一下索引:

        public class ESClient {

            private RestHighLevelClient esClient;

            @Before
            public void createClient() {
                // 創(chuàng)建es客戶端
                esClient = new RestHighLevelClient(
                    RestClient.builder(new HttpHost("192.168.56.10"9200"http"))
                );
            }

            @After
            public void closeClient() throws IOException {
                // 關(guān)閉客戶端
                esClient.close();
            }

            @Test
            public void testIndex() throws IOException {
                // 創(chuàng)建索引
                CreateIndexRequest request = new CreateIndexRequest("emp");
                CreateIndexResponse response = esClient.indices().create(request, RequestOptions.DEFAULT);
                boolean result = response.isAcknowledged();
                if (result) {
                    System.out.println("索引創(chuàng)建成功...");
                } else {
                    System.out.println("索引創(chuàng)建失敗...");
                }
            }
        }

        首先需要?jiǎng)?chuàng)建ElasticSearch客戶端,指定ip、端口和http協(xié)議,然后就可以創(chuàng)建索引了,通過CreateIndexRequest即可創(chuàng)建一個(gè)索引。其它的索引操作也都是類似的:

        @Test
        public void testIndex() throws IOException {
            // 查詢索引
            GetIndexRequest request = new GetIndexRequest("emp");
            GetIndexResponse response = esClient.indices().get(request, RequestOptions.DEFAULT);
            System.out.println(response.getAliases());
            System.out.println(response.getSettings());
            System.out.println(response.getMappings());
        }

        通過GetIndexRequest即可查詢索引,在response中可以獲取別名、設(shè)置及其映射等信息,運(yùn)行結(jié)果:

        {emp=[]}
        {emp={"index.creation_date":"1621085161553","index.number_of_replicas":"1","index.number_of_shards":"1","index.provided_name":"emp","index.uuid":"kOqizSD5R9Kq4W-5mKinfw","index.version.created":"7040299"}}
        {emp=org.elasticsearch.cluster.metadata.MappingMetadata@d42716bd}

        最后是刪除索引:

        @Test
        public void testIndex() throws IOException {
            // 刪除索引
            DeleteIndexRequest request = new DeleteIndexRequest("emp");
            AcknowledgedResponse response = esClient.indices().delete(request, RequestOptions.DEFAULT);
            boolean result = response.isAcknowledged();
            if (result) {
                System.out.println("索引刪除成功");
            }else {
                System.out.println("索引刪除失敗");
            }
        }

        接著是Java項(xiàng)目中對于文檔的操作,文檔需要傳入的是json數(shù)據(jù),所以我們先創(chuàng)建一個(gè)Bean:

        @Data
        @NoArgsConstructor
        @AllArgsConstructor
        public class Employee {

            private String name;
            private Integer age;
            private String sex;
            private Double salary;
        }

        創(chuàng)建文檔過程如下:

        @Test
        public void testDoc() throws IOException {
            // 創(chuàng)建文檔
            IndexRequest request = new IndexRequest();
            // 指定索引
            request.index("emp");
            // 指定文檔id
            request.id("1");
            Employee employee = new Employee("張三"30"男"6000.0);
            // 將對象轉(zhuǎn)為json數(shù)據(jù)
            Gson gson = new Gson();
            String empJson = gson.toJson(employee);
            // 傳入json數(shù)據(jù)
            request.source(empJson, XContentType.JSON);
            IndexResponse response = esClient.index(request, RequestOptions.DEFAULT);
            System.out.println(response.getResult());
        }

        若是想要更新文檔,則只需使用UpdateRequest即可:

        @Test
        public void testDoc() throws IOException {
            // 更新文檔
            UpdateRequest request = new UpdateRequest();
            // 指定索引
            request.index("emp");
            // 指定文檔id
            request.id("1");
            // 更新
            request.doc(XContentType.JSON,"salary",5000.0);
            UpdateResponse response = esClient.update(request, RequestOptions.DEFAULT);
            System.out.println(response.getResult());
        }

        接下來的查詢文檔和刪除文檔操作,相信不用往下看,大家也應(yīng)該會了,這里就直接貼代碼了:

        @Test
        public void testDoc() throws IOException {
            // 查詢文檔
            GetRequest request = new GetRequest();
            // 指定索引
            request.index("emp");
            // 指定id
            request.id("1");
            GetResponse response = esClient.get(request, RequestOptions.DEFAULT);
            System.out.println(response.getSourceAsString());
        }
        @Test
        public void testDoc() throws IOException {
            // 刪除文檔
            DeleteRequest request = new DeleteRequest();
            // 指定索引
            request.index("emp");
            // 指定id
            request.id("1");
            DeleteResponse response = esClient.delete(request, RequestOptions.DEFAULT);
            System.out.println(response.toString());
        }

        Java API中也提供了批量創(chuàng)建和刪除文檔的方法,一起來看看如何操作:

        @Test
        public void testDoc() throws IOException {
            // 批量創(chuàng)建文檔
            BulkRequest request = new BulkRequest();
            // 創(chuàng)建對象
            Employee employee = new Employee("張三"20"男"5000.0);
            Employee employee2 = new Employee("李四"30"男"6000.0);
            Employee employee3 = new Employee("王五"40"男"6000.0);
            // 添加到request中
            request.add(new IndexRequest().index("emp").id("1").source(new Gson().toJson(employee), XContentType.JSON));
            request.add(new IndexRequest().index("emp").id("2").source(new Gson().toJson(employee2), XContentType.JSON));
            request.add(new IndexRequest().index("emp").id("3").source(new Gson().toJson(employee3), XContentType.JSON));
            // 執(zhí)行批量創(chuàng)建
            BulkResponse response = esClient.bulk(request, RequestOptions.DEFAULT);
            System.out.println(Arrays.toString(response.getItems()));
        }
        @Test
        public void testDoc() throws IOException {
            // 批量刪除文檔
            BulkRequest request = new BulkRequest();
            // 添加到request中
            request.add(new DeleteRequest().index("emp").id("1"));
            request.add(new DeleteRequest().index("emp").id("2"));
            request.add(new DeleteRequest().index("emp").id("3"));
            // 執(zhí)行批量刪除
            BulkResponse response = esClient.bulk(request, RequestOptions.DEFAULT);
            System.out.println(Arrays.toString(response.getItems()));
        }

        高級查詢

        最后我們來看看Java API該如何實(shí)現(xiàn)ElasticSearch中的高級查詢。

        @Test
        public void testQuery() throws IOException {
            // 高級查詢
            SearchRequest request = new SearchRequest();
            // 指定索引
            request.indices("emp");
            // 指定查詢條件
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery());// 匹配所有
            request.source(searchSourceBuilder);
            SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
            SearchHits hits = response.getHits();
            System.out.println(hits.getTotalHits()); // 獲取結(jié)果總記錄數(shù)
            System.out.println(response.getTook()); // 獲取查詢耗費(fèi)時(shí)間
            hits.forEach(System.out::println);
        }

        QueryBuilders類中提供了一些已經(jīng)寫好的查詢條件,比如這里的matchAllQuery,表示匹配所有,即:全量匹配,看看運(yùn)行結(jié)果:

        3 hits
        1.3s
        {
          "_index" : "emp",
          "_type" : "_doc",
          "_id" : "1",
          "_score" : 1.0,
          "_source" : {
            "name" : "張三",
            "age" : 20,
            "sex" : "男",
            "salary" : 5000.0
          }
        }
        {
          "_index" : "emp",
          "_type" : "_doc",
          "_id" : "2",
          "_score" : 1.0,
          "_source" : {
            "name" : "李四",
            "age" : 30,
            "sex" : "男",
            "salary" : 6000.0
          }
        }
        {
          "_index" : "emp",
          "_type" : "_doc",
          "_id" : "3",
          "_score" : 1.0,
          "_source" : {
            "name" : "王五",
            "age" : 40,
            "sex" : "男",
            "salary" : 6000.0
          }
        }

        條件查詢:

        @Test
        public void testQuery() throws IOException {
            // 高級查詢
            SearchRequest request = new SearchRequest();
            // 指定索引
            request.indices("emp");
            // 指定查詢條件
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().query(QueryBuilders.termQuery("age",30));
            request.source(searchSourceBuilder);
            SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
            SearchHits hits = response.getHits();
            hits.forEach(System.out::println);
        }

        調(diào)用QueryBuilders的termQuery方法能夠指定具體的查詢條件,此時(shí)便可以查詢出年齡為30歲的用戶信息:

        {"name":"李四","age":30,"sex":"男","salary":6000.0}

        分頁查詢:

        @Test
        public void testQuery() throws IOException {
            SearchRequest request = new SearchRequest(); // 高級查詢
            request.indices("emp"); // 指定索引
            // 指定查詢條件
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery());// 匹配所有
            searchSourceBuilder.from(0); // 指定頁碼
            searchSourceBuilder.size(2); // 指定每頁的記錄數(shù)
            request.source(searchSourceBuilder);
            SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
            SearchHits hits = response.getHits();
            System.out.println(hits.getTotalHits());
            hits.forEach(hit -> {
                System.out.println(hit.getSourceAsString());
            });
        }

        通過from和size方法即可指定分頁參數(shù),此時(shí)將會查詢到第一頁的兩條數(shù)據(jù):

        3 hits
        {"name":"張三","age":20,"sex":"男","salary":5000.0}
        {"name":"李四","age":30,"sex":"男","salary":6000.0}

        組合查詢:

        @Test
        public void testQuery() throws IOException {
            SearchRequest request = new SearchRequest(); // 高級查詢
            request.indices("emp"); // 指定索引
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
            BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
            // 指定查詢條件
            queryBuilder.must(QueryBuilders.matchQuery("age"30))
                .must(QueryBuilders.matchQuery("sex""男"));
            searchSourceBuilder.query(queryBuilder);
            request.source(searchSourceBuilder);
            SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
            SearchHits hits = response.getHits();
            hits.forEach(hit -> {
                System.out.println(hit.getSourceAsString());
            });
        }

        此時(shí)將查詢出年齡為30歲的男性用戶,若是想查詢年齡為20或者30的用戶,則修改查詢條件:

        queryBuilder.should(QueryBuilders.matchQuery("age"20))
            .should(QueryBuilders.matchQuery("age""30"));

        范圍查詢:

        @Test
        public void testQuery() throws IOException {
            SearchRequest request = new SearchRequest(); // 高級查詢
            request.indices("emp"); // 指定索引
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
            RangeQueryBuilder queryBuilder = QueryBuilders.rangeQuery("age");
            // 指定查詢范圍
            queryBuilder.gte(20).lte(40);
            searchSourceBuilder.query(queryBuilder);
            request.source(searchSourceBuilder);
            SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
            SearchHits hits = response.getHits();
            hits.forEach(hit -> {
                System.out.println(hit.getSourceAsString());
            });
        }

        此時(shí)將查詢年齡在20~30歲之間的用戶數(shù)據(jù)。

        好了,以上就是本篇文章的全部內(nèi)容了。我覺得寫的還算通俗易懂,希望對你入門有幫助吧!

        本文作者:汪偉俊 為Java技術(shù)迷專欄作者 投稿,未經(jīng)允許請勿轉(zhuǎn)載。

        1、Intellij IDEA這樣 配置注釋模板,讓你瞬間高出一個(gè)逼格!
        2、吊炸天的 Docker 圖形化工具 Portainer,必須推薦給你!
        3、最牛逼的 Java 日志框架,性能無敵,橫掃所有對手!
        4、把Redis當(dāng)作隊(duì)列來用,真的合適嗎?
        5、驚呆了,Spring Boot居然這么耗內(nèi)存!你知道嗎?
        6、全網(wǎng)最全 Java 日志框架適配方案!還有誰不會?
        7、Spring中毒太深,離開Spring我居然連最基本的接口都不會寫了

        點(diǎn)分享

        點(diǎn)收藏

        點(diǎn)點(diǎn)贊

        點(diǎn)在看

        瀏覽 142
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

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

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        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>
            69成人网 | 在线观看国产一级片 | 欧美老妇操逼 | 杨门后传之乱淫h侵犯杨门女将 | 国产国语自产精品视频二区在 | AV毛片| 日韩三级毛片 | 毛片链接 | 中文字幕日本有码 | 美女日逼片 |