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

搜索引擎ElasticSearch分布式搜索和分析引擎學(xué)習(xí),SpringBoot整合ES個(gè)人心得

這篇具有很好參考價(jià)值的文章主要介紹了搜索引擎ElasticSearch分布式搜索和分析引擎學(xué)習(xí),SpringBoot整合ES個(gè)人心得。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

ElasticSearch

Elasticsearch是一個(gè)基于Lucene的搜索服務(wù)器。它提供了一個(gè)分布式多用戶能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java語言開發(fā)的,并作為Apache許可條款下的開放源碼發(fā)布,是一種流行的企業(yè)級搜索引擎。Elasticsearch用于云計(jì)算中,能夠達(dá)到實(shí)時(shí)搜索,穩(wěn)定,可靠,快速,安裝使用方便。官方客戶端在Java、.NET(C#)、PHP、Python、Apache Groovy、Ruby和許多其他語言中都是可用的。根據(jù)DB-Engines的排名顯示,Elasticsearch是最受歡迎的企業(yè)搜索引擎,其次是Apache Solr,也是基于Lucene

如京東,淘寶

Lucene是一個(gè)Java語言的搜索引擎類庫,是Apache公司的頂級項(xiàng)目,由DougCutting于1999年研發(fā)。官網(wǎng)地址: https:// lucene.apache.org/

重要性:

  1. 分布式的實(shí)時(shí)文件存儲,每個(gè)字段都被索引并可被搜索
  2. 實(shí)時(shí)分析的分布式搜索引擎
  3. 可以擴(kuò)展到上百臺服務(wù)器,處理PB級結(jié)構(gòu)化或非結(jié)構(gòu)化數(shù)據(jù)

倒排索引

倒排索引的概念是基于MySQL這樣的正向索引而言的

正向索引

搜索引擎ElasticSearch分布式搜索和分析引擎學(xué)習(xí),SpringBoot整合ES個(gè)人心得,搜索引擎,elasticsearch,分布式

但如果是基于title做模糊查詢,只能是逐行掃描數(shù)據(jù),流程如下:

  1. 用戶搜索數(shù)據(jù),條件是title符合“%手機(jī)%
  2. 逐行獲取數(shù)據(jù),比如id為1的數(shù)據(jù)
  3. 判斷數(shù)據(jù)中的title是否符合用戶搜索條件
  4. 如果符合則放入結(jié)果集,不符合則丟棄?;氐讲襟E1

逐行掃描,也就是全表掃描,隨著數(shù)據(jù)量增加,其查詢效率也會越來越低。當(dāng)數(shù)據(jù)量達(dá)到數(shù)百萬時(shí),就是一場災(zāi)難。

倒排索引

倒排索引中有兩個(gè)非常重要的概念:

  • 文檔Document:用來搜索的數(shù)據(jù),其中的每一條數(shù)據(jù)就是一個(gè)文檔。例如一個(gè)網(wǎng)頁、一個(gè)商品信息
  • 詞條Term:對文檔數(shù)據(jù)或用戶搜索數(shù)據(jù),利用某種算法分詞,得到的具備含義的詞語就是詞條。例如:我是中國人,就可以分為:我、是、中國人、中國、國人這樣的幾個(gè)詞條

創(chuàng)建倒排索引是對正向索引的一種特殊處理,流程如下:

  1. 將每一個(gè)文檔的數(shù)據(jù)利用算法分詞,得到一個(gè)個(gè)詞條
  2. 創(chuàng)建表,每行數(shù)據(jù)包括詞條、詞條所在文檔id、位置等信息
  3. 因?yàn)樵~條唯一性,可以給詞條創(chuàng)建索引,例如hash表結(jié)構(gòu)索引

搜索引擎ElasticSearch分布式搜索和分析引擎學(xué)習(xí),SpringBoot整合ES個(gè)人心得,搜索引擎,elasticsearch,分布式

倒排索引的搜索流程如下(以搜尋“華為手機(jī)”為例)

  1. 用戶輸入條件 “華為手機(jī)” 進(jìn)行搜索。
  2. 對用戶輸入內(nèi)容分詞,得到詞條: 華為 、 手機(jī) 。
  3. 拿著詞條在倒排索引中查找,可以得到包含詞條的文檔id:1、2、3。
  4. 拿著文檔id到正向索引中查找具體文檔

搜索引擎ElasticSearch分布式搜索和分析引擎學(xué)習(xí),SpringBoot整合ES個(gè)人心得,搜索引擎,elasticsearch,分布式

雖然要先查詢倒排索引,再查詢倒排索引,但是無論是詞條、還是文檔id都建立了索引,查詢速度非??欤o需全表掃描。

正向和倒排

  • 正向索引是最傳統(tǒng)的,根據(jù)id索引的方式。但根據(jù)詞條查詢時(shí),必須先逐條獲取每個(gè)文檔,然后判斷文檔中是否包含所需要的詞條,是根據(jù)文檔找詞條的過程。
  • 倒排索引則相反,是先找到用戶要搜索的詞條,根據(jù)詞條得到保護(hù)詞條的文檔的id,然后根據(jù)id獲取文檔。是根據(jù)詞條找文檔的過程

正向索引

優(yōu)點(diǎn):

  1. 可以給多個(gè)字段創(chuàng)建索引
  2. 根據(jù)索引字段搜索、排序速度非???/li>

缺點(diǎn):

  1. 根據(jù)非索引字段,或者索引字段中的部分詞條查找時(shí),只能全表掃描

倒排索引

優(yōu)點(diǎn):

  1. 根據(jù)詞條搜索、模糊搜索時(shí),速度非???/li>

缺點(diǎn):

  1. 只能給詞條創(chuàng)建索引,而不是字段
  2. 無法根據(jù)字段做排序

ES的一些概念

elasticsearch中有很多獨(dú)有的概念,與mysql中略有差別,但也有相似之處

文檔和字段

elasticsearch是面向**文檔(Document)**存儲的,可以是數(shù)據(jù)庫中的一條商品數(shù)據(jù),一個(gè)訂單信息。文檔數(shù)據(jù)會被序列化為json格式后存儲在elasticsearch中:

搜索引擎ElasticSearch分布式搜索和分析引擎學(xué)習(xí),SpringBoot整合ES個(gè)人心得,搜索引擎,elasticsearch,分布式

而Json文檔中往往包含很多的字段(Field),類似于數(shù)據(jù)庫中的列

索引和映射

索引(Index),就是相同類型的文檔的集合。

例如:

  • 所有用戶文檔,就可以組織在一起,稱為用戶的索引;
  • 所有商品的文檔,可以組織在一起,稱為商品的索引;
  • 所有訂單的文檔,可以組織在一起,稱為訂單的索引;

搜索引擎ElasticSearch分布式搜索和分析引擎學(xué)習(xí),SpringBoot整合ES個(gè)人心得,搜索引擎,elasticsearch,分布式

因此,我們可以把索引當(dāng)做是數(shù)據(jù)庫中的表。

數(shù)據(jù)庫的表會有約束信息,用來定義表的結(jié)構(gòu)、字段的名稱、類型等信息。因此,索引庫中就有映射(mapping),是索引中文檔的字段約束信息,類似表的結(jié)構(gòu)約束。

MySQL和ElasticSearch

我們統(tǒng)一的把mysql與elasticsearch的概念做一下對比

搜索引擎ElasticSearch分布式搜索和分析引擎學(xué)習(xí),SpringBoot整合ES個(gè)人心得,搜索引擎,elasticsearch,分布式

ES環(huán)境安裝

ES環(huán)境需要ES和分詞器

環(huán)境搭建步驟:

  1. windows版ES下載:網(wǎng)址https://www.elastic.co/cn/downloads/elasticsearch
  2. 下載分詞器(4IK分詞器):https://github.com/medcl/elasticsearch-analysis-ik/releases
  3. 解壓縮ES,并且在解壓縮的plugins創(chuàng)建ik文件夾
  4. 將4IK分詞器解壓后的所有文件拷貝到創(chuàng)建的ik文件夾下

啟動ES:

  1. 找到ES文件夾下的bin文件夾,雙擊文件 elasticsearch.bat(彈出窗口不要關(guān)閉)
  2. 瀏覽器訪問localhost:9200能看到j(luò)son代表啟動成功

4IK分詞器

作用:

  1. 創(chuàng)建倒排索引時(shí)對文檔分詞
  2. 用戶搜索時(shí),對輸入的內(nèi)容分詞

IK分詞器的模式:

  1. ik_smart:智能切分,粗粒度
  2. ik_max_word:最細(xì)切分,細(xì)粒度

索引庫操作

索引庫就類似數(shù)據(jù)庫表,mapping映射就類似表的結(jié)構(gòu)。

我們要向es中存儲數(shù)據(jù),必須先創(chuàng)建“庫”和“表”。

mapping映射屬性

mapping是對索引庫中文檔的約束,常見的mapping屬性包括:

type:字段數(shù)據(jù)類型,常見的簡單類型有:

  • 字符串:text(可分詞的文本)、keyword(精確值,例如:品牌、國家、ip地址)
  • 數(shù)值:long、integer、short、byte、double、float
  • 布爾:boolean
  • 日期:date
  • 對象:object

index:是否創(chuàng)建索引,默認(rèn)為true

analyzer:使用哪種分詞器

properties:該字段的子字段

Eg:

{
  "age": 18,
  "weight": 70.2,
  "isMarried": false,
  "info": "apesourceJavaEE王講師",
  "email": "wangls@163.com",
  "score": [99.1, 99.5, 98.9],
  "name": {
    "firstName": "師傅",
    "lastName": "王"
  }
}

對應(yīng)的每個(gè)字段映射(mapping):

  • age:類型為 integer;參與搜索,因此需要index為true;無需分詞器
  • weight:類型為float;參與搜索,因此需要index為true;無需分詞器
  • isMarried:類型為boolean;參與搜索,因此需要index為true;無需分詞器
  • info:類型為字符串,需要分詞,因此是text;參與搜索,因此需要index為true;分詞器可以用ik_smart
  • email:類型為字符串,但是不需要分詞,因此是keyword;不參與搜索,因此需要index為false;無需分詞器
  • score:雖然是數(shù)組,但是我們只看元素的類型,類型為float;參與搜索,因此需要index為true;無需分詞器
  • name:類型為object,需要定義多個(gè)子屬性
    • name.firstName;類型為字符串,但是不需要分詞,因此是keyword;參與搜索,因此需要index為true;無需分詞器
    • name.lastName;類型為字符串,但是不需要分詞,因此是keyword;參與搜索,因此需要
    • index為true;無需分詞器

創(chuàng)建索引庫和映射

基本語法:

  • 請求方式:PUT
  • 請求路徑:/索引庫名,可以自定義
  • 請求參數(shù):mapping

格式:

{
    "mappings":{
        "properties":{
            "age":{
                "type":"integer"
            },
            "isMarried":{
                "type":"boolean"
            },
            "name":{
                "type":"text",
                "analyzer":"ik_smart"
            },
            "info":{
                "type":"text",
                "index":"false"
            },
            "pet":{
                "properties":{
                    "dog":{
                        "type":"text"
                    },
                    "cat":{
                         "type":"text"   
                    }
                }
            }
        }
    }
}

搜索引擎ElasticSearch分布式搜索和分析引擎學(xué)習(xí),SpringBoot整合ES個(gè)人心得,搜索引擎,elasticsearch,分布式

Postman測試創(chuàng)建索引庫和映射

查詢索引庫

基本語法

  • 請求方式:GET
  • 請求路徑:/索引庫名
  • 請求參數(shù):無

格式:

GET /索引庫名

eg:postman發(fā)送GET請求:localhost:9200/teachers

修改索引庫

倒排索引結(jié)構(gòu)雖然不復(fù)雜,但是一旦數(shù)據(jù)結(jié)構(gòu)改變(比如改變了分詞器),就需要重新創(chuàng)建倒排索引,這簡直是災(zāi)難。因此索引庫一旦創(chuàng)建,無法修改mapping。

雖然無法修改mapping中已有的字段,但是卻允許添加新的字段到mapping中,因?yàn)椴粫Φ古潘饕a(chǎn)生影響。

語法說明:

PUT /索引庫名/_mapping
{
  "properties": {
    "新字段名":{
      "type": "integer"
    }
  }
}

eg:postman發(fā)送PUT請求:localhost:9200/teachers/_mapping

搜索引擎ElasticSearch分布式搜索和分析引擎學(xué)習(xí),SpringBoot整合ES個(gè)人心得,搜索引擎,elasticsearch,分布式

刪除索引庫

語法:

  • 請求方式:DELETE
  • 請求路徑:/索引庫名
  • 請求參數(shù):無

格式:

DELETE /索引庫名

postman發(fā)送DELETE請求:localhost:9200/teachers

總結(jié):

  1. 創(chuàng)建索引庫:PUT /索引庫名
  2. 查詢索引庫:GET /索引庫名
  3. 刪除索引庫:DELETE /索引庫名
  4. 添加字段:PUT /索引庫名/_mapping

文檔操作

新增文檔

語法:

POST /索引庫名/_doc/文檔id
{
  "字段1": "值1",
  "字段2": "值2",
  "字段3": {
    "子屬性1": "值3",
    "子屬性2": "值4"
  },
  // ...
}

eg:

POST請求:localhost:9200/teachers/_doc/1

{
    "info":"java程序開發(fā)工程師",
    "age":"23",
    "name":"詹姆斯高斯林",
    "pet":{
        "拉布拉多":"旺財(cái)",
        "英短":"小老弟"
    }
}

查詢文檔

根據(jù)rest風(fēng)格,新增是post,查詢應(yīng)該是get,不過查詢一般都需要條件,這里我們把文檔id帶上。

語法:

GET /{索引庫名稱}/_doc/{id}

查看數(shù)據(jù):

GET請求:localhost:9200/teachers/_doc/1

localhost:9200/teachers/_doc/1

刪除文檔

刪除使用DELETE請求,同樣,需要根據(jù)id進(jìn)行刪除

語法:

DELETE /{索引庫名}/_doc/id值

eg:

DELETE請求

localhost:9200/teachers/_doc/1

修改文檔

  • 全量修改:直接覆蓋原來的文檔
  • 增量修改:修改文檔中的部分字段

全量修改

全量修改是覆蓋原來的文檔,其本質(zhì)是:

  • 根據(jù)指定的id刪除文檔
  • 新增一個(gè)相同id的文檔

**注意:**如果根據(jù)id刪除時(shí),id不存在,第二步的新增也會執(zhí)行,也就從修改變成了新增操作了

語法:

PUT /{索引庫名}/_doc/文檔id
{
  "字段1": "值1",
  "字段2": "值2",
  // ... 略
}

eg:

postman發(fā)送PUT請求:localhost:9200/teachers/_doc/1

{
    "info":"python程序開發(fā)工程",
    "name":"吉多范羅蘇姆",
    "age":"22",
    "pet":{
        "拉布拉多":"旺財(cái)",
        "英短":"小老弟"
    }
}

全量修改

增量修改是只修改指定id匹配的文檔中的部分字段

語法:

POST /{索引庫名}/_update/文檔id
{
  "doc": {
    "字段名": "新的值",
  }
}

eg:

postman發(fā)送POST請求:localhost:9200/teachers/_update/1

{
    "doc":{
        "name":"詹姆斯高斯林再牛逼也進(jìn)不了谷歌"
    }
}

總結(jié):

  1. 創(chuàng)建文檔:POST /{索引庫名}/_doc/文檔id { json文檔 }
  2. 查詢文檔:GET /{索引庫名}/_doc/文檔id
  3. 刪除文檔:DELETE /{索引庫名}/_doc/文檔id
  4. 修改文檔:
    • 全量修改:PUT /{索引庫名}/_doc/文檔id { json文檔 }
    • 增量修改:POST /{索引庫名}/_update/文檔id { “doc”: {字段}}

RestAPI

ES官方提供了各種不同語言的客戶端,用來操作ES。這些客戶端的本質(zhì)就是組裝DSL語句,通過http請求發(fā)送給ES。官方文檔地址:https://www.elastic.co/guide/en/elasticsearch/client/index.html

其中的Java Rest Client又包括兩種:

  • Java Low Level Rest Client
  • Java High Level Rest Client

主要介紹Java High Level Rest Client

數(shù)據(jù)庫建表語句

CREATE TABLE `tb_hotel` (
  `id` bigint(20) NOT NULL COMMENT '酒店id',
  `name` varchar(255) NOT NULL COMMENT '酒店名稱;例:7天酒店',
  `address` varchar(255) NOT NULL COMMENT '酒店地址;例:航頭路',
  `price` int(10) NOT NULL COMMENT '酒店價(jià)格;例:329',
  `score` int(2) NOT NULL COMMENT '酒店評分;例:45,就是4.5分',
  `brand` varchar(32) NOT NULL COMMENT '酒店品牌;例:如家',
  `city` varchar(32) NOT NULL COMMENT '所在城市;例:上海',
  `star_name` varchar(16) DEFAULT NULL COMMENT '酒店星級,從低到高分別是:1星到5星,1
  鉆到5鉆',
  `business` varchar(255) DEFAULT NULL COMMENT '商圈;例:虹橋',
  `latitude` varchar(32) NOT NULL COMMENT '緯度;例:31.2497',
  `longitude` varchar(32) NOT NULL COMMENT '經(jīng)度;例:120.3925',
  `pic` varchar(255) DEFAULT NULL COMMENT '酒店圖片;例:/img/1.jpg',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

mapping映射分析

酒店數(shù)據(jù)的索引庫結(jié)構(gòu):

{
  "mappings": {
    "properties": {
      "id": {
        "type": "keyword"
      },
      "name":{
        "type": "text",
        "analyzer": "ik_max_word",
        "copy_to": "all"
      },
      "address":{
        "type": "keyword",
        "index": false,
        "copy_to": "all"
      },
      "price":{
        "type": "integer"
      },
      "score":{
        "type": "integer"
      },
      "brand":{
        "type": "keyword",
        "copy_to": "all"
      },
      "city":{
        "type": "keyword",
        "copy_to": "all"
      },
      "starName":{
        "type": "keyword"
      },
      "business":{
        "type": "keyword"
      },
      "location":{
        "type": "geo_point"
      },
      "pic":{
        "type": "keyword",
        "index": false
      },
      "all":{
        "type": "text",
        "analyzer": "ik_max_word"
      }
    }
  }
}

幾個(gè)特殊字段說明:

location:地理坐標(biāo),里面包含精度、緯度

all:一個(gè)組合字段,其目的是將多字段的值 利用copy_to合并,提供給用戶搜索

地理坐標(biāo)說明:

搜索引擎ElasticSearch分布式搜索和分析引擎學(xué)習(xí),SpringBoot整合ES個(gè)人心得,搜索引擎,elasticsearch,分布式

copy_to說明:

搜索引擎ElasticSearch分布式搜索和分析引擎學(xué)習(xí),SpringBoot整合ES個(gè)人心得,搜索引擎,elasticsearch,分布式

JAVA中使用ES

初始化RestClient

在elasticsearch提供的API中,與elasticsearch一切交互都封裝在一個(gè)名為RestHighLevelClient的類中,必須先完成這個(gè)對象的初始化,建立與elasticsearch的連接。

在Spring Boot中使用ES三步驟:

  1. 引入es的RestHighLevelClient依賴

    <dependency>
      <groupId>org.elasticsearch.client</groupId>
      <artifactId>elasticsearch-rest-high-level-client</artifactId>
    </dependency>
    
  2. 因?yàn)镾pringBoot默認(rèn)的ES版本是7.6.2,所以我們需要覆蓋默認(rèn)的ES版本

    <properties>
      <java.version>1.8</java.version>
      <elasticsearch.version>7.12.0</elasticsearch.version>
    </properties>
    
  3. 初始化RestHighLevelClient

    將RestHighLevelClient注入容器,可以寫配置類,也可以寫在啟動類中

    @Bean
    public RestHighLevelClient restHighLevelClient(){
      RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(
      	HttpHost.create("http://localhost:9200")
    	));
    }
    

創(chuàng)建索引庫

  1. 準(zhǔn)備索引庫映射字符串

    public class HotelConstants {
      public static final String MAPPING_TEMPLATE = "{\n" +
        "  \"mappings\": {\n" +
        "    \"properties\": {\n" +
        "      \"id\": {\n" +
        "        \"type\": \"keyword\"\n" +
        "      },\n" +
        "      \"name\":{\n" +
        "        \"type\": \"text\",\n" +
        "        \"analyzer\": \"ik_max_word\",\n" +
        "        \"copy_to\": \"all\"\n" +
        "      },\n" +
        "      \"address\":{\n" +
        "        \"type\": \"keyword\",\n" +
        "        \"index\": false\n" +
        "      },\n" +
        "      \"price\":{\n" +
        "        \"type\": \"integer\"\n" +
        "      },\n" +
        "      \"score\":{\n" +
        "        \"type\": \"integer\"\n" +
        "      },\n" +
        "      \"brand\":{\n" +
        "        \"type\": \"keyword\",\n" +
        "        \"copy_to\": \"all\"\n" +
        "      },\n" +
        "      \"city\":{\n" +
        "        \"type\": \"keyword\",\n" +
        "        \"copy_to\": \"all\"\n" +
        "      },\n" +
        "      \"starName\":{\n" +
        "        \"type\": \"keyword\"\n" +
        "      },\n" +
        "      \"business\":{\n" +
        "        \"type\": \"keyword\"\n" +
        "      },\n" +
        "      \"location\":{\n" +
        "        \"type\": \"geo_point\"\n" +
        "      },\n" +
        "      \"pic\":{\n" +
        "        \"type\": \"keyword\",\n" +
        "        \"index\": false\n" +
        "      },\n" +
        "      \"all\":{\n" +
        "        \"type\": \"text\",\n" +
        "        \"analyzer\": \"ik_max_word\"\n" +
        "      }\n" +
        "    }\n" +
        "  }\n" +
        "}";
    }
    
  2. 索引庫的操作

    @SpringBootTest
    class SpringbootEs01ApplicationTests {
    
      private RestHighLevelClient client;
    
      @BeforeEach
      void setUp(){
        this.client = new RestHighLevelClient(RestClient.builder(
          HttpHost.create("http://localhost:9200")
        ));
      }
    
      @AfterEach
      void tearDown() throws Exception{
        this.client.close();
      }
    
      // 判斷索引庫是否存在
      @Test
      void testExistsHotelIndex() throws Exception {
        GetIndexRequest request = new GetIndexRequest("hotels");
        boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
        System.err.println(exists ? "索引庫已經(jīng)存在":"索引庫不存在");
      }
    
      // 創(chuàng)建索引庫
      @Test
      void createHotelIndex() throws Exception{
        // 創(chuàng)建Request對象
        CreateIndexRequest request = new CreateIndexRequest("hotels");
        // 準(zhǔn)備請求的參數(shù):DSL語句
        request.source(HotelConstants.MAPPING_TEMPLATE, XContentType.JSON);
        // 發(fā)送請求
        client.indices().create(request,RequestOptions.DEFAULT);
      }
    
      // 刪除索引庫
      @Test
      void delteHotelIndex() throws Exception{
        // 創(chuàng)建Request對象
        DeleteIndexRequest request = new DeleteIndexRequest("hotels");
        // 發(fā)送請求
        client.indices().delete(request,RequestOptions.DEFAULT);
      }
    
    }
    

總結(jié)

JavaRestClient操作elasticsearch的流程基本類似。核心是client.indices()方法來獲取索引庫的操作對象

索引庫操作的基本步驟:

  1. 初始化RestHighLevelClient
  2. 創(chuàng)建XxxIndexRequest。XXX是Create、Get、Delete
  3. 準(zhǔn)備DSL( Create時(shí)需要,其它是無參)
  4. 發(fā)送請求。調(diào)用RestHighLevelClient#indices().xxx()方法,xxx是create、exists、delete

文檔操作

演示在juint單元測試中進(jìn)行,準(zhǔn)備

@SpringBootTest
public class HotelDocumentTests {
    // 核心對象
    private RestHighLevelClient client;

    // 需要從數(shù)據(jù)庫中查數(shù)據(jù)存入es,裝配業(yè)務(wù)
    @Autowired(required = false)
    private IHotelService service;

    @BeforeEach
    void setUp(){
        this.client = new RestHighLevelClient(RestClient.builder(
                HttpHost.create("http://localhost:9200")
        ));
    }

    @AfterEach
    void tearDown() throws  Exception{
        this.client.close();
    }
}
  • 從數(shù)據(jù)庫中新增一條數(shù)據(jù)到ES

    @Test
    void addDocument() throws Exception{
      // 從數(shù)據(jù)庫查詢一條數(shù)據(jù)
      Hotel hotel = service.getById(395434);
      System.out.println(hotel);
      // 轉(zhuǎn)換為文檔類型
      HotelDoc hotelDoc = new HotelDoc(hotel);
      // 將文檔類型轉(zhuǎn)為JSON格式
      String json = JSON.toJSONString(hotelDoc);
      // 準(zhǔn)備request請求對象
      IndexRequest request = new IndexRequest("hotels").id(hotelDoc.getId().toString());
      // 準(zhǔn)備JSON文檔
      request.source(json, XContentType.JSON);
      // 發(fā)送請求
      client.index(request, RequestOptions.DEFAULT);
    }
    
  • 從ES中刪除一條數(shù)據(jù)

    @Test
    void deleteDocument() throws Exception{
      // 準(zhǔn)備刪除請求Request
      DeleteRequest request = new DeleteRequest("hotels", "395434");
      client.delete(request,RequestOptions.DEFAULT);
    }
    
  • 修改ES中的數(shù)據(jù)

    修改有兩種方式:

    1. 全量修改:本質(zhì)是先根據(jù)id刪除,再新增
    2. 增量修改:修改文檔中的指定字段值
    3. 在RestClient的API中,全量修改與新增的API完全一致
    @Test
    void updateDocument() throws  Exception{
      // 準(zhǔn)備修改請求UpdateRequest
      UpdateRequest request = new UpdateRequest("hotels", "395434");
      // 準(zhǔn)備請求參數(shù)(要修改的數(shù)據(jù)內(nèi)容)
      request.doc(
        "name","W酒店",
        "city","西安",
        "price","2000",
        "starName","五星級"
      );
    }
    
  • 批量新增數(shù)據(jù)到ES中

    @Test
    void addAllDocument() throws  Exception{
      // 數(shù)據(jù)庫全查
      List<Hotel> hotels = service.list();
      // 準(zhǔn)備請求
      BulkRequest bulkRequest = new BulkRequest();
      // 準(zhǔn)備參數(shù)
      for(Hotel hotel : hotels){
        // 類型轉(zhuǎn)化
        HotelDoc hotelDoc = new HotelDoc(hotel);
        // 請求添加數(shù)據(jù)
        bulkRequest.add(new IndexRequest("hotels").id(hotelDoc.getId().toString()).source(JSON.toJSONString(hotelDoc),XContentType.JSON));
      }
      // 發(fā)送請求
      client.bulk(bulkRequest,RequestOptions.DEFAULT);
    }
    

總結(jié)

文檔操作的基本步驟:

  1. 初始化RestHighLevelClient
  2. 創(chuàng)建XxxRequest。XXX是Index、Get、Update、Delete、Bulk
  3. 準(zhǔn)備參數(shù)(Index、Update、Bulk時(shí)需要)
  4. 發(fā)送請求。調(diào)用RestHighLevelClient#.xxx()方法,xxx是index、get、update、delete、bulk
  5. 解析結(jié)果(Get時(shí)需要)

查詢文檔操作

Elasticsearch提供了基于JSON的DSL(Domain Specific Language)來定義查詢。常見的查詢類型包括:

==查詢所有:==查詢出所有數(shù)據(jù),一般測試用(不會顯示出所有,自帶分頁功能)。例如:match_all

==全文檢索(full text)查詢:==利用分詞器對用戶輸入內(nèi)容分詞,然后去倒排索引庫中匹配。例如:

  • match_query:單字段查詢
  • multi_match_query:多字段查詢,任意一個(gè)字段符合條件就算符合查詢條件

==準(zhǔn)確查詢:==根據(jù)精確詞條值查找數(shù)據(jù),一般是查找keyword、數(shù)值、日期、boolean等類型字段。例如

  • ids:id查詢
  • range:根據(jù)值的范圍查詢
  • term:根據(jù)詞條精確值查詢

==地理(geo)查詢:==根據(jù)經(jīng)緯度查詢。例如:

  • geo_distance
  • geo_bounding_box

==復(fù)合(compound)查詢:==復(fù)合查詢可以將上述各種查詢條件組合起來,合并查詢條件。例如:

  • bool

  • function_score

  • 查詢一條數(shù)據(jù)

    @Test
    void getDocumentById() throws  Exception{
      // 準(zhǔn)備查詢請求GetRequest
      GetRequest getRequest = new GetRequest("hotels", "395434");
      // 發(fā)送請求,得到響應(yīng)
      GetResponse response = client.get(getRequest, RequestOptions.DEFAULT);
      // 解析響應(yīng)結(jié)果
      String json = response.getSourceAsString();
      HotelDoc hotelDoc = JSON.parseObject(json,HotelDoc.class);
      System.out.println(hotelDoc);
    }
    
  • 解析對象方法

    // 解析對象方法
    public void show(SearchResponse response){
        // 解析響應(yīng)
        SearchHits searchHits = response.getHits();
        long total = searchHits.getTotalHits().value;
        System.out.println("總計(jì)查詢數(shù)據(jù):"+total+"條");
        SearchHit[] hits = searchHits.getHits();
        for(SearchHit hit :hits){
            /// 獲取文檔source
            String json = hit.getSourceAsString();
            // 反序列化
            HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
            System.out.println("hotelDoc="+hotelDoc);
        }
    }
    
  • 全查

    @Test
    void findAllDocument() throws IOException{
      // 準(zhǔn)備request
      SearchRequest request = new SearchRequest("hotels");
    
      // 2.準(zhǔn)備DSL,QueryBuilders構(gòu)造查詢條件
      request.source().query(QueryBuilders.matchAllQuery());
    
      // 3.發(fā)送請求
      SearchResponse response = client.search(request, RequestOptions.DEFAULT);
      show(response);
    }
    
  • 全文索引----查詢all字段內(nèi)容中含有如家的

    @Test
    void testMacth() throws IOException{
        // 準(zhǔn)備請求
        SearchRequest request = new SearchRequest("hotels");
        // 準(zhǔn)備DSL
        request.source().
                query(QueryBuilders.matchQuery("all","如家"));
    
        // 發(fā)送請求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        show(response);
    }
    
  • 全文索引----多字段查詢

    @Test
    void testMultiMatchQuery()throws IOException {
      // 準(zhǔn)備請求
      SearchRequest request = new SearchRequest("hotels");
      // 準(zhǔn)備DSL
      request.source()
        .query(QueryBuilders.multiMatchQuery("上海","name","city"));
      // 發(fā)送請求
      SearchResponse response = client.search(request, RequestOptions.DEFAULT);
      show(response);
    }
    
  • 精確查詢1

    // term:根據(jù)詞條精準(zhǔn)查詢(字段等值查詢)
    @Test
    void testTerm() throws  IOException{
      // 準(zhǔn)備請求
      SearchRequest request = new SearchRequest("hotels");
      // 準(zhǔn)備DSL
      request.source()
        .query(QueryBuilders.termQuery("brand","希爾頓"));
      // 發(fā)送請求
      SearchResponse response = client.search(request, RequestOptions.DEFAULT);
      show(response);
    }
    
  • 精確查詢2

    // range范圍查詢
    @Test
    void  testRange() throws IOException {
      // 準(zhǔn)備請求
      SearchRequest request = new SearchRequest("hotels");
      // 準(zhǔn)備DSL
      request.source()
        .query(QueryBuilders.rangeQuery("price").gte(200).lte(300));
      // 發(fā)送請求
      SearchResponse response = client.search(request, RequestOptions.DEFAULT);
      show(response);
    }
    
  • 精確查詢3

    // ids查詢
    @Test
    void testIds() throws IOException  {
      // 準(zhǔn)備請求
      SearchRequest request = new SearchRequest("hotels");
      // 準(zhǔn)備DSL
      request.source()
        .query(QueryBuilders.idsQuery().addIds("395434","3532"));
      // 發(fā)送請求
      SearchResponse response = client.search(request, RequestOptions.DEFAULT);
      show(response);
    }
    
  • 復(fù)合查詢

    // bool復(fù)合查詢
    @Test
    void testBool() throws IOException{
      // 準(zhǔn)備請求
      SearchRequest request = new SearchRequest("hotels");
      // 準(zhǔn)備條件
      /*-- 方式1  ----*/
      //        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
      //        boolQueryBuilder.must(QueryBuilders.termQuery("city","北京"));
      //        boolQueryBuilder.filter(QueryBuilders.rangeQuery("price").lte(500));
      //        // 準(zhǔn)備DSL
      //        request.source().query(boolQueryBuilder);
    
      /*---- 方式2 ----*/
      request.source()
        .query(QueryBuilders.boolQuery()
               .must(QueryBuilders.termQuery("city","北京"))
               .filter(QueryBuilders.rangeQuery("price").lte(500)));
    
      // 發(fā)送請求
      SearchResponse response = client.search(request, RequestOptions.DEFAULT);
      show(response);
    }
    
  • 自定義分頁規(guī)則

    // 自定義分頁方式
    @Test
    void testPageAndSort() throws IOException{
      int page = 1;   //頁碼
      int size = 5;   //步長
    
      String searchName="希爾頓"; // 查詢條件
    
      // 準(zhǔn)備請求
      SearchRequest request = new SearchRequest("hotels");
      if (searchName == null){
        request.source().query(QueryBuilders.matchAllQuery());
      }else {
        request.source().query(QueryBuilders.matchQuery("brand",searchName));
      }
      // 自定義分頁
      request.source().from((page-1)*size).size(size);
      // 自定義排序
      request.source().sort("price", SortOrder.DESC);
      SearchResponse response = client.search(request, RequestOptions.DEFAULT);
      show(response);
    }
    

總結(jié)

SpringBoot中整合ES的實(shí)現(xiàn)步驟 :

  1. 導(dǎo)pom文件ES的坐標(biāo)

    <properties>
        <java.version>1.8</java.version>
        <elasticsearch.version>7.12.0</elasticsearch.version>
    </properties>
    
  2. 寫ES配置類

    @Configuration
    public class ElasticSearchConfig {
        @Bean
        public RestHighLevelClient restHighLevelClient(){
            return new RestHighLevelClient(RestClient.builder(
               HttpHost.create("http://localhost:9200")
            ));
        }
    }
    
  3. 寫ES映射Mapping

  4. 建立ES索引庫

    public void createEs() throws IOException {
      GetIndexRequest request = new GetIndexRequest("employee");
      // 判斷索引庫是否存在
      boolean exists = restHighLevelClient.indices().exists(request, RequestOptions.DEFAULT);
      // 如果不存在建庫
      if(!exists){
        // 創(chuàng)建Request對象
        CreateIndexRequest createIndexRequest = new CreateIndexRequest("employee");
        // 準(zhǔn)備請求的參數(shù)DSL語句
        createIndexRequest.source(EmployeeConstants.MAPPING_TEMPLATE, XContentType.JSON);
        // 發(fā)送請求
        restHighLevelClient.indices().create(createIndexRequest,RequestOptions.DEFAULT);
      }
    }
    
  5. 把數(shù)據(jù)庫中的數(shù)據(jù)添加到ES中

    public void addAllEmployee() throws Exception{
        // 數(shù)據(jù)庫全查
        List<Employee> list = employeeService.list();
        // 準(zhǔn)備請求
        BulkRequest bulkRequest = new BulkRequest();
        for(Employee e : list){
            bulkRequest.add(new IndexRequest("employee").id(e.getId().toString()).source(JSON.toJSONString(e),XContentType.JSON));
        }
        // 發(fā)送請求
        restHighLevelClient.bulk(bulkRequest,RequestOptions.DEFAULT);
    }
    
  6. 業(yè)務(wù)中查詢ES,修改添加刪除數(shù)據(jù)庫同步ES

  7. 寫解析

    // 解析對象方法
    public void show(SearchResponse response){
      // 解析響應(yīng)
      SearchHits searchHits = response.getHits();
      long total = searchHits.getTotalHits().value;
      System.out.println("總計(jì)查詢數(shù)據(jù):"+total+"條");
      SearchHit[] hits = searchHits.getHits();
      for(SearchHit hit :hits){
        /// 獲取文檔source
        String json = hit.getSourceAsString();
        // 反序列化
        HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
        System.out.println("hotelDoc="+hotelDoc);
      }
    }
    

注意:操作ES需要裝配核心對象RestHighLevelClient文章來源地址http://www.zghlxwxcb.cn/news/detail-758498.html

到了這里,關(guān)于搜索引擎ElasticSearch分布式搜索和分析引擎學(xué)習(xí),SpringBoot整合ES個(gè)人心得的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

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

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

相關(guān)文章

  • 分布式搜索引擎elasticsearch(一)

    分布式搜索引擎elasticsearch(一)

    elasticsearch是一款非常強(qiáng)大的開源搜索引擎,可以幫助我們從海量數(shù)據(jù)中快速找到需要的內(nèi)容。 elasticsearch是elastic stack的核心,負(fù)責(zé)存儲、搜索、分析數(shù)據(jù)。 文檔(document):每條數(shù)據(jù)就是一個(gè)文檔 詞條(term):文檔按照語義分成的詞語 倒排索引中包含兩部分內(nèi)容: 詞條詞

    2024年02月02日
    瀏覽(29)
  • # 分布式搜索引擎-- elasticsearch基礎(chǔ)

    # 分布式搜索引擎-- elasticsearch基礎(chǔ)

    elasticsearch是一款非常強(qiáng)大的開源搜索引擎,具備非常多強(qiáng)大功能,可以幫助我們從海量數(shù)據(jù)中快速找到需要的內(nèi)容,,可以用來實(shí)現(xiàn)搜索、日志統(tǒng)計(jì)、分析、系統(tǒng)監(jiān)控等功能 ? ?是以elasticsearch為核心的技術(shù)棧,都包括: ElasticSearch(存儲,計(jì)算,搜索數(shù)據(jù)) kibana(數(shù)據(jù)可視化) Logstas

    2024年03月27日
    瀏覽(31)
  • Elasticsearch 分布式搜索引擎 速學(xué)

    Elasticsearch 分布式搜索引擎 速學(xué)

    ????????elasticsearch是一款非常強(qiáng)大的開源搜索引擎,具備非常多強(qiáng)大功能,可以幫助我們從海量數(shù)據(jù)中快速找到需要的內(nèi)容,它結(jié)合kibana、Logstash、Beats,也就是elastic stack(ELK)。它被廣泛應(yīng)用在日志數(shù)據(jù)分析、實(shí)時(shí)監(jiān)控等領(lǐng)域,而elasticsearch是elastic stack的核心,負(fù)責(zé)存儲

    2024年02月03日
    瀏覽(18)
  • 分布式搜索引擎ElasticSearch——基礎(chǔ)

    分布式搜索引擎ElasticSearch——基礎(chǔ)

    什么是elasticsearch elasticsearch的發(fā)展 https://lucene.apache.org/ https://www.elastic.co/cn/ 正向索引和倒排索引 安裝elasticsearch,kibana https://github.com/medcl/elasticsearch-analysis-ik 部署單點(diǎn)es 創(chuàng)建網(wǎng)絡(luò) 因?yàn)槲覀冞€需要部署kibana容器,因此需要讓es和kibana容器互聯(lián)。這里先創(chuàng)建一個(gè)網(wǎng)絡(luò): 加載鏡像

    2024年01月17日
    瀏覽(33)
  • 分布式搜索引擎-elasticsearch基礎(chǔ)

    分布式搜索引擎-elasticsearch基礎(chǔ)

    elasticsearch是一款非常強(qiáng)大的開源搜索引擎,可以幫助我們從海量數(shù)據(jù)中快速找到需要的內(nèi)容。 elasticsearch結(jié)合kibana、Logstash、Beats,也就是elastic stack(ELK)。被廣泛應(yīng)用在 日志數(shù)據(jù)分析 、 實(shí)時(shí)監(jiān)控 等領(lǐng)域。 elasticsearch是elastic stack的核心,負(fù)責(zé)存儲、搜索、分析數(shù)據(jù)。 Lucen

    2024年03月20日
    瀏覽(30)
  • 分布式搜索引擎ElasticSearch——深入elasticSearch

    分布式搜索引擎ElasticSearch——深入elasticSearch

    聚合的分類 DSL實(shí)現(xiàn)Bucket聚合 DSL實(shí)現(xiàn)Metric聚合 RestAPI實(shí)現(xiàn)聚合 https://github.com/medcl/elasticsearch-analysis-pinyin DSL實(shí)現(xiàn)自動補(bǔ)全查詢 Completion Suggester 修改酒店索引庫數(shù)據(jù)結(jié)構(gòu) RestAPI實(shí)現(xiàn)自動補(bǔ)全查詢 實(shí)現(xiàn)酒店搜索頁面輸入框的自動補(bǔ)全 數(shù)據(jù)同步思路分析 利用MQ實(shí)現(xiàn)mysql與elasticsearch數(shù)

    2024年01月17日
    瀏覽(54)
  • 微服務(wù)---分布式搜索引擎 elasticsearch基礎(chǔ)

    微服務(wù)---分布式搜索引擎 elasticsearch基礎(chǔ)

    1.1.1.elasticsearch的作用 elasticsearch是一款非常強(qiáng)大的開源搜索引擎,具備非常多強(qiáng)大功能,可以幫助我們從海量數(shù)據(jù)中快速找到需要的內(nèi)容 例如: 在GitHub搜索代碼 在電商網(wǎng)站搜索商品 在百度搜索答案 在打車軟件搜索附近的車 1.1.2.ELK技術(shù)棧 elasticsearch結(jié)合kibana、Logstash、Beats,

    2024年02月04日
    瀏覽(29)
  • ElasticSearch分布式搜索引擎(兩萬字詳解)

    ElasticSearch分布式搜索引擎(兩萬字詳解)

    elasticsearch是一款非常強(qiáng)大的開源搜索引擎,具備非常多強(qiáng)大功能,可以幫助我們從海量數(shù)據(jù)中快速找到需要的內(nèi)容 elasticsearch結(jié)合kibana、Logstash、Beats,也就是elastic stack(ELK)。被廣泛應(yīng)用在日志數(shù)據(jù)分析、實(shí)時(shí)監(jiān)控等領(lǐng)域: 而elasticsearch是elastic stack的核心,負(fù)責(zé)存儲、搜索

    2024年01月25日
    瀏覽(54)
  • Elasticsearch 分布式全文搜索引擎原理解析

    作者:禪與計(jì)算機(jī)程序設(shè)計(jì)藝術(shù) Elasticsearch是一個(gè)開源的分布式全文搜索引擎,它可以近實(shí)時(shí)地存儲、檢索數(shù)據(jù)。本系列文章將從以下幾個(gè)方面對Elasticsearch進(jìn)行深入分析: Elasticsearch的主要組成部分 索引、類型和映射(Mapping) 搜索請求處理流程 查詢緩存機(jī)制 Elasticsearch集群

    2024年02月05日
    瀏覽(30)
  • 分布式搜索引擎Elasticsearch基礎(chǔ)入門學(xué)習(xí)

    分布式搜索引擎Elasticsearch基礎(chǔ)入門學(xué)習(xí)

    Elasticsearh 是 elastic.co 公司開發(fā)的分布式搜索引擎。 Elasticsearch(簡稱ES)是一個(gè)開源的分布式、高度可擴(kuò)展的全文搜索和分析引擎。它能夠快速、近乎實(shí)時(shí)的存儲、搜索和分析大量數(shù)據(jù)。適用于包括文本、數(shù)字、地理空間、結(jié)構(gòu)化和非結(jié)構(gòu)化數(shù)據(jù)等在內(nèi)的所有類型數(shù)據(jù)。 它通

    2024年02月03日
    瀏覽(37)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包