<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

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

          共 26761字,需瀏覽 54分鐘

           ·

          2021-05-19 12:35


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

          安裝ElasticSearch

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


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

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


          等待啟動(dòng)完成后,訪問(wèn)http://localhost:9200/:


          看到此界面則說(shuō)明ElasticSearch啟動(dòng)成功了。

          相關(guān)概念

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

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

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

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

          我們可以將其類比到關(guān)系型數(shù)據(jù)庫(kù)中,索引就是一個(gè)數(shù)據(jù)庫(kù),類型就是一張數(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ù),它是如何做到的呢?

          我們先來(lái)看一張關(guān)系型數(shù)據(jù)庫(kù)中的數(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ù)開(kāi)始遍歷到最后一條數(shù)據(jù)。來(lái)看看ElasticSearch是如何做的,它采用的是一種叫 倒排索引 的方式,即:在插入數(shù)據(jù)的時(shí)候就建立了一張關(guān)鍵字與id的對(duì)應(yīng)表:

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

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

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

          索引

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

          創(chuàng)建索引

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

          查詢索引

          查詢索引非常簡(jiǎn)單,我們只需要修改剛才的請(qǐng)求方式為GET即可:


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

          刪除索引

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

          文檔

          我們?cè)賮?lái)看看文檔的相關(guān)操作,文檔對(duì)應(yīng)關(guān)系型數(shù)據(jù)庫(kù)中的數(shù)據(jù)行。

          創(chuàng)建文檔

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


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

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

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

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


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

          查詢文檔

          通過(guò)GET請(qǐng)求方式即可查詢文檔:


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

          更新文檔

          更新文檔分為兩種方式:

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

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


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


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

          刪除文檔

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

          高級(jí)查詢

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

          條件查詢

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


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

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


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

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


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

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

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

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

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

          多條件查詢

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


          請(qǐng)求體參數(shù)為:

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

          其中 query 表示查詢,不必多說(shuō), 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)我們?cè)跈z索某個(gè)關(guān)鍵字的時(shí)候,ElasticSearch仍然能夠準(zhǔn)備查詢到相關(guān)信息,這是因?yàn)镋lasticSearch會(huì)將文字分詞并與文檔id作對(duì)應(yīng)形成倒排索引,相關(guān)內(nèi)容我們?cè)谇懊婢鸵呀?jīng)接觸到了,這就是ElasticSearch的全文檢索功能。當(dāng)我們的姓名是兩個(gè)漢字時(shí):

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

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

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

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

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

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

          聚合查詢

          若是想對(duì)查詢的數(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

          下面我們來(lái)看看在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/

          這樣就可以啟動(dòng)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

          啟動(dòng)完成后,同樣測(cè)試一下:



          接下來(lái)我們就可以在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)建索引了,通過(guò)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());
          }

          通過(guò)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)目中對(duì)于文檔的操作,文檔需要傳入的是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)建文檔過(guò)程如下:

          @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);
              // 將對(duì)象轉(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());
          }

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

          @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)建和刪除文檔的方法,一起來(lái)看看如何操作:

          @Test
          public void testDoc() throws IOException {
              // 批量創(chuàng)建文檔
              BulkRequest request = new BulkRequest();
              // 創(chuàng)建對(duì)象
              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()));
          }

          高級(jí)查詢

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

          @Test
          public void testQuery() throws IOException {
              // 高級(jí)查詢
              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 {
              // 高級(jí)查詢
              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}

          分頁(yè)查詢:

          @Test
          public void testQuery() throws IOException {
              SearchRequest request = new SearchRequest(); // 高級(jí)查詢
              request.indices("emp"); // 指定索引
              // 指定查詢條件
              SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery());// 匹配所有
              searchSourceBuilder.from(0); // 指定頁(yè)碼
              searchSourceBuilder.size(2); // 指定每頁(yè)的記錄數(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());
              });
          }

          通過(guò)from和size方法即可指定分頁(yè)參數(shù),此時(shí)將會(huì)查詢到第一頁(yè)的兩條數(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(); // 高級(jí)查詢
              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(); // 高級(jí)查詢
              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ù)。

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

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

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

          點(diǎn)分享

          點(diǎn)收藏

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

          點(diǎn)在看

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

          手機(jī)掃一掃分享

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

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  8050网午夜一级 | 操操操操逼操操操操 | 无码性爱视频 | 操逼逼AV | av在线一区二区 av在线资源观看 |