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

分布式搜索引擎elasticsearch(一)

這篇具有很好參考價值的文章主要介紹了分布式搜索引擎elasticsearch(一)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

5.1 初始elasticsearch

elasticsearch是一款非常強大的開源搜索引擎,可以幫助我們從海量數(shù)據(jù)中快速找到需要的內(nèi)容。

elasticsearch是elastic stack的核心,負責存儲、搜索、分析數(shù)據(jù)。

分布式搜索引擎elasticsearch(一),微服務,jenkins,運維

5.1.1正向索引

分布式搜索引擎elasticsearch(一),微服務,jenkins,運維

5.1.2elasticsearch采用倒排索引:

文檔(document):每條數(shù)據(jù)就是一個文檔

詞條(term):文檔按照語義分成的詞語

分布式搜索引擎elasticsearch(一),微服務,jenkins,運維

倒排索引中包含兩部分內(nèi)容:

詞條詞典(Term Dictionary):記錄所有詞條,以及詞條與倒排列表(Posting List)之間的關(guān)系,會給詞條創(chuàng)建索引,提高查詢和插入效率

倒排列表(Posting List):記錄詞條所在的文檔id、詞條出現(xiàn)頻率 、詞條在文檔中的位置等信息

文檔id:用于快速獲取文檔

詞條頻率(TF):文檔在詞條出現(xiàn)的次數(shù),用于評分

分布式搜索引擎elasticsearch(一),微服務,jenkins,運維

1、elasticsearch是面向文檔存儲的,可以是數(shù)據(jù)庫中的一條商品數(shù)據(jù),一個訂單信息。

文檔數(shù)據(jù)會被序列化為json格式后存儲在elasticsearch中。

分布式搜索引擎elasticsearch(一),微服務,jenkins,運維

2、索引(index):相同類型的文檔的集合

5.1.3mysql與Elasticsearch對比

MySQL

Elasticsearch

說明

Table

Index

索引(index),就是文檔的集合,類似數(shù)據(jù)庫的表(table)

Row

Document

文檔(Document),就是一條條的數(shù)據(jù),類似數(shù)據(jù)庫中的行(Row),文檔都是JSON格式

Column

Field

字段(Field),就是JSON文檔中的字段,類似數(shù)據(jù)庫中的列(Column)

Schema

Mapping

Mapping(映射)是索引中文檔的約束,例如字段類型約束。類似數(shù)據(jù)庫的表結(jié)構(gòu)(Schema)

SQL

DSL

DSL是elasticsearch提供的JSON風格的請求語句,用來操作elasticsearch,實現(xiàn)CRUD

Mysql:擅長事務類型操作,可以確保數(shù)據(jù)的安全和一致性

Elasticsearch:擅長海量數(shù)據(jù)的搜索、分析、計算

分布式搜索引擎elasticsearch(一),微服務,jenkins,運維

5.1.4安裝elasticsearch

1.部署單點es

1.1.創(chuàng)建網(wǎng)絡

因為我們還需要部署kibana容器,因此需要讓es和kibana容器互聯(lián)。這里先創(chuàng)建一個網(wǎng)絡:


docker network create es-net
1.2.加載鏡像

這里我們采用elasticsearch的7.12.1版本的鏡像,這個鏡像體積非常大,接近1G。不建議大家自己pull。

課前資料提供了鏡像的tar包:

大家將其上傳到虛擬機中,然后運行命令加載即可:


# 導入數(shù)據(jù)
docker load -i es.tar

同理還有kibana的tar包也需要這樣做。

1.3.運行

運行docker命令,部署單點es:


docker run -d \
	--name es \
    -e "ES_JAVA_OPTS=-Xms512m -Xmx512m" \
    -e "discovery.type=single-node" \
    -v es-data:/usr/share/elasticsearch/data \
    -v es-plugins:/usr/share/elasticsearch/plugins \
    --privileged \
    --network es-net \
    -p 9200:9200 \
    -p 9300:9300 \
elasticsearch:7.12.1

命令解釋:

  • -e "cluster.name=es-docker-cluster":設(shè)置集群名稱

  • -e "http.host=0.0.0.0":監(jiān)聽的地址,可以外網(wǎng)訪問

  • -e "ES_JAVA_OPTS=-Xms512m -Xmx512m":內(nèi)存大小

  • -e "discovery.type=single-node":非集群模式

  • -v es-data:/usr/share/elasticsearch/data:掛載邏輯卷,綁定es的數(shù)據(jù)目錄

  • -v es-logs:/usr/share/elasticsearch/logs:掛載邏輯卷,綁定es的日志目錄

  • -v es-plugins:/usr/share/elasticsearch/plugins:掛載邏輯卷,綁定es的插件目錄

  • --privileged:授予邏輯卷訪問權(quán)

  • --network es-net :加入一個名為es-net的網(wǎng)絡中

  • -p 9200:9200:端口映射配置

在瀏覽器中輸入:http://192.168.153.131:9200/ 即可看到elasticsearch的響應結(jié)果:

分布式搜索引擎elasticsearch(一),微服務,jenkins,運維

2.部署kibana

kibana可以給我們提供一個elasticsearch的可視化界面,便于我們學習。

2.1.部署

運行docker命令,部署kibana


docker run -d \
--name kibana \
-e ELASTICSEARCH_HOSTS=http://es:9200 \
--network=es-net \
-p 5601:5601  \
kibana:7.12.1
  • --network es-net :加入一個名為es-net的網(wǎng)絡中,與elasticsearch在同一個網(wǎng)絡中

  • -e ELASTICSEARCH_HOSTS=http://es:9200":設(shè)置elasticsearch的地址,因為kibana已經(jīng)與elasticsearch在一個網(wǎng)絡,因此可以用容器名直接訪問elasticsearch

  • -p 5601:5601:端口映射配置

kibana啟動一般比較慢,需要多等待一會,可以通過命令:


docker logs -f kibana

查看運行日志,說明成功:

此時,在瀏覽器輸入地址訪問:http://192.168.153.131:5601,即可看到結(jié)果

2.2.DevTools

kibana中提供了一個DevTools界面:

這個界面中可以編寫DSL來操作elasticsearch。并且對DSL語句有自動補全功能。

分布式搜索引擎elasticsearch(一),微服務,jenkins,運維

分布式搜索引擎elasticsearch(一),微服務,jenkins,運維

語法說明:

  • POST:請求方式
  • /_analyze:請求路徑,這里省略了虛擬機IP地址:9200,有kibana幫我們補充
  • 請求參數(shù),json風格:
  • analyzer:分詞器類型,這里是默認的standard分詞器
  • text:要分詞的內(nèi)容

3.安裝IK分詞器

3.1.在線安裝ik插件(較慢)
# 進入容器內(nèi)部
docker exec -it elasticsearch /bin/bash

# 在線下載并安裝
./bin/elasticsearch-plugin  install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.12.1/elasticsearch-analysis-ik-7.12.1.zip

#退出
exit
#重啟容器
docker restart elasticsearch
3.2.離線安裝ik插件(推薦)
1)查看數(shù)據(jù)卷目錄

安裝插件需要知道elasticsearch的plugins目錄位置,而我們用了數(shù)據(jù)卷掛載,因此需要查看elasticsearch的數(shù)據(jù)卷目錄,通過下面命令查看:


docker volume inspect es-plugins

顯示結(jié)果:

[
    {
        "CreatedAt": "2022-05-06T10:06:34+08:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/es-plugins/_data",
        "Name": "es-plugins",
        "Options": null,
        "Scope": "local"
    }
]

說明plugins目錄被掛載到了:/var/lib/docker/volumes/es-plugins/_data 這個目錄中。

2)解壓縮分詞器安裝包

下面我們需要把課前資料中的ik分詞器解壓縮,重命名為ik

3)上傳到es容器的插件數(shù)據(jù)卷中

也就是/var/lib/docker/volumes/es-plugins/_data :

4)重啟容器
# 4、重啟容器
docker restart es

# 查看es日志
docker logs -f es
5)測試:

IK分詞器包含兩種模式:

  1. ik_smart:最少切分
  2. ik_max_word:最細切分
GET /_analyze
{
  "analyzer": "ik_max_word",
  "text": "黑馬程序員學習java太棒了"
}

結(jié)果:

{
  "tokens" : [
    {
      "token" : "黑馬",
      "start_offset" : 0,
      "end_offset" : 2,
      "type" : "CN_WORD",
      "position" : 0
    },
    {
      "token" : "程序員",
      "start_offset" : 2,
      "end_offset" : 5,
      "type" : "CN_WORD",
      "position" : 1
    },
    {
      "token" : "程序",
      "start_offset" : 2,
      "end_offset" : 4,
      "type" : "CN_WORD",
      "position" : 2
    },
    {
      "token" : "員",
      "start_offset" : 4,
      "end_offset" : 5,
      "type" : "CN_CHAR",
      "position" : 3
    },
    {
      "token" : "學習",
      "start_offset" : 5,
      "end_offset" : 7,
      "type" : "CN_WORD",
      "position" : 4
    },
    {
      "token" : "java",
      "start_offset" : 7,
      "end_offset" : 11,
      "type" : "ENGLISH",
      "position" : 5
    },
    {
      "token" : "太棒了",
      "start_offset" : 11,
      "end_offset" : 14,
      "type" : "CN_WORD",
      "position" : 6
    },
    {
      "token" : "太棒",
      "start_offset" : 11,
      "end_offset" : 13,
      "type" : "CN_WORD",
      "position" : 7
    },
    {
      "token" : "了",
      "start_offset" : 13,
      "end_offset" : 14,
      "type" : "CN_CHAR",
      "position" : 8
    }
  ]
}
POST /_analyze
{
  "text":"黑馬程序員學習Java太棒了",
  "analyzer": "ik_smart"
}
{
  "tokens" : [
    {
      "token" : "黑馬",
      "start_offset" : 0,
      "end_offset" : 2,
      "type" : "CN_WORD",
      "position" : 0
    },
    {
      "token" : "程序員",
      "start_offset" : 2,
      "end_offset" : 5,
      "type" : "CN_WORD",
      "position" : 1
    },
    {
      "token" : "學習",
      "start_offset" : 5,
      "end_offset" : 7,
      "type" : "CN_WORD",
      "position" : 2
    },
    {
      "token" : "java",
      "start_offset" : 7,
      "end_offset" : 11,
      "type" : "ENGLISH",
      "position" : 3
    },
    {
      "token" : "太棒了",
      "start_offset" : 11,
      "end_offset" : 14,
      "type" : "CN_WORD",
      "position" : 4
    }
  ]
}
3.3 擴展詞詞典

隨著互聯(lián)網(wǎng)的發(fā)展,“造詞運動”也越發(fā)的頻繁。出現(xiàn)了很多新的詞語,在原有的詞匯列表中并不存在。比如:“奧力給”,“傳智播客” 等。

所以我們的詞匯也需要不斷的更新,IK分詞器提供了擴展詞匯的功能。

  1. 打開IK分詞器config目錄:

分布式搜索引擎elasticsearch(一),微服務,jenkins,運維

2)在IKAnalyzer.cfg.xml配置文件內(nèi)容添加:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
        <comment>IK Analyzer 擴展配置</comment>
        <!--用戶可以在這里配置自己的擴展字典 *** 添加擴展詞典-->
        <entry key="ext_dict">ext.dic</entry>
</properties>

3)新建一個 ext.dic,可以參考config目錄下復制一個配置文件進行修改


傳智播客
奧力給

4)重啟elasticsearch


docker restart es

日志中已經(jīng)成功加載ext.dic配置文件

5)測試效果:

GET /_analyze
{
  "analyzer": "ik_max_word",
  "text": "傳智播客Java就業(yè)超過90%,奧力給!"
}
注意當前文件的編碼必須是 UTF-8 格式,嚴禁使用Windows記事本編輯
3.4 停用詞詞典

在互聯(lián)網(wǎng)項目中,在網(wǎng)絡間傳輸?shù)乃俣群芸?,所以很多語言是不允許在網(wǎng)絡上傳遞的,如:關(guān)于宗教、政治等敏感詞語,那么我們在搜索時也應該忽略當前詞匯。

IK分詞器也提供了強大的停用詞功能,讓我們在索引時就直接忽略當前的停用詞匯表中的內(nèi)容。

1)IKAnalyzer.cfg.xml配置文件內(nèi)容添加:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
        <comment>IK Analyzer 擴展配置</comment>
        <!--用戶可以在這里配置自己的擴展字典-->
        <entry key="ext_dict">ext.dic</entry>
         <!--用戶可以在這里配置自己的擴展停止詞字典  *** 添加停用詞詞典-->
        <entry key="ext_stopwords">stopword.dic</entry>
</properties>

3)在 stopword.dic 添加停用詞


yrh

4)重啟elasticsearch


# 重啟服務
docker restart elasticsearch
docker restart kibana

# 查看 日志
docker logs -f elasticsearch

日志中已經(jīng)成功加載stopword.dic配置文件

5)測試效果:

GET /_analyze
{
  "analyzer": "ik_max_word",
  "text": "傳智播客Java就業(yè)率超過95%,奧力給!"
}
注意當前文件的編碼必須是 UTF-8 格式,嚴禁使用Windows記事本編輯

4.部署es集群

部署es集群可以直接使用docker-compose來完成,不過要求你的Linux虛擬機至少有4G的內(nèi)存空間

首先編寫一個docker-compose文件,內(nèi)容如下:


version: '2.2'
services:
  es01:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.12.1
    container_name: es01
    environment:
      - node.name=es01
      - cluster.name=es-docker-cluster
      - discovery.seed_hosts=es02,es03
      - cluster.initial_master_nodes=es01,es02,es03
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - data01:/usr/share/elasticsearch/data
    ports:
      - 9200:9200
    networks:
      - elastic
  es02:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.12.1
    container_name: es02
    environment:
      - node.name=es02
      - cluster.name=es-docker-cluster
      - discovery.seed_hosts=es01,es03
      - cluster.initial_master_nodes=es01,es02,es03
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - data02:/usr/share/elasticsearch/data
    networks:
      - elastic
  es03:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.12.1
    container_name: es03
    environment:
      - node.name=es03
      - cluster.name=es-docker-cluster
      - discovery.seed_hosts=es01,es02
      - cluster.initial_master_nodes=es01,es02,es03
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - data03:/usr/share/elasticsearch/data
    networks:
      - elastic

volumes:
  data01:
    driver: local
  data02:
    driver: local
  data03:
    driver: local

networks:
  elastic:
    driver: bridge

Run docker-compose to bring up the cluster:


docker-compose up

總結(jié):

分詞器的作用是什么?

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

IK分詞器有幾種模式?

  • ik_smart:智能切分,粗粒度
  • ik_max_word:最細切分,細粒度

IK分詞器如何拓展詞條?如何停用詞條?

  • 利用config目錄的IkAnalyzer.cfg.xml文件添加拓展詞典和停用詞典
  • 在詞典中添加拓展詞條或者停用詞條

5.2 索引庫操作

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

字符串:text(可分詞的文本)、keyword(精確值,例如:品牌、國家、ip地址)

數(shù)值:long、integer、short、byte、double、float、

布爾:boolean

日期:date

對象:object

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

analyzer:使用哪種分詞器

properties:該字段的子字段

ES中通過Restful請求操作索引庫、文檔。請求內(nèi)容用DSL語句來表示。

分布式搜索引擎elasticsearch(一),微服務,jenkins,運維

索引庫操作有哪些?

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

5.3 文檔操作

新增文檔的DSL語法如下:

分布式搜索引擎elasticsearch(一),微服務,jenkins,運維

修改文檔

分布式搜索引擎elasticsearch(一),微服務,jenkins,運維

文檔操作有哪些?

創(chuàng)建文檔:POST /索引庫名/_doc/文檔id { json文檔 }

查詢文檔:GET /索引庫名/_doc/文檔id

刪除文檔:DELETE /索引庫名/_doc/文檔id

修改文檔:

  • 全量修改:PUT /索引庫名/_doc/文檔id { json文檔 }
  • 增量修改:POST /索引庫名/_update/文檔id { "doc": {字段}}

Dynamic Mapping

插入文檔時,es會檢查文檔中的字段是否有mapping,如果沒有則按照默認mapping規(guī)則來創(chuàng)建索引。

如果默認mapping規(guī)則不符合你的需求,一定要自己設(shè)置字段mapping

5.4 RestClient操作索引庫

ES官方提供了各種不同語言的客戶端,用來操作ES。這些客戶端的本質(zhì)就是組裝DSL語句,通過http請求發(fā)送給ES。官方文檔地址:Elasticsearch Clients | Elastic

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

  • Java Low Level Rest Client

  • Java High Level Rest Client

分布式搜索引擎elasticsearch(一),微服務,jenkins,運維

我們學習的是Java HighLevel Rest Client客戶端API

5.4.1.導入數(shù)據(jù)

首先導入課前資料提供的數(shù)據(jù)庫數(shù)據(jù):

分布式搜索引擎elasticsearch(一),微服務,jenkins,運維

數(shù)據(jù)結(jié)構(gòu)如下:

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?'酒店價格;例: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;

5.4.2.導入項目

然后導入課前資料提供的項目:

分布式搜索引擎elasticsearch(一),微服務,jenkins,運維

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

分布式搜索引擎elasticsearch(一),微服務,jenkins,運維

5.4.3.mapping映射分析

創(chuàng)建索引庫,最關(guān)鍵的是mapping映射,而mapping映射要考慮的信息包括:

  • 字段名

  • 字段數(shù)據(jù)類型

  • 是否參與搜索

  • 是否需要分詞

  • 如果分詞,分詞器是什么?

其中:

  • 字段名、字段數(shù)據(jù)類型,可以參考數(shù)據(jù)表結(jié)構(gòu)的名稱和類型

  • 是否參與搜索要分析業(yè)務來判斷,例如圖片地址,就無需參與搜索

  • 是否分詞呢要看內(nèi)容,內(nèi)容如果是一個整體就無需分詞,反之則要分詞

  • 分詞器,我們可以統(tǒng)一使用ik_max_word

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

PUT /hotel
{
? "mappings": {
? ? "properties": {
? ? ? "id": {
? ? ? ? "type": "keyword"
? ? ? },
? ? ? "name":{
? ? ? ? "type": "text",
? ? ? ? "analyzer": "ik_max_word",
? ? ? ? "copy_to": "all"
? ? ? },
? ? ? "address":{
? ? ? ? "type": "keyword",
? ? ? ? "index": false
? ? ? },
? ? ? "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"
? ? ? }
? ? }
? }
}

幾個特殊字段說明:

  • location:地理坐標,里面包含精度、緯度

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

地理坐標說明:

分布式搜索引擎elasticsearch(一),微服務,jenkins,運維

copy_to說明:

分布式搜索引擎elasticsearch(一),微服務,jenkins,運維

5.4.4.初始化RestClient

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

分為三步:

1)引入es的RestHighLevelClient依賴:

        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <version>7.12.1</version>
        </dependency>

2)初始化RestHighLevelClient:

初始化的代碼如下:

public class HotelIndex {
    private RestHighLevelClient client;
    @Test
    void testCreateHotelIndex() throws IOException {
        // 1.創(chuàng)建Request對象
        CreateIndexRequest request = new CreateIndexRequest("hotel");
        // 2.請求參數(shù),MAPPING_TEMPLATE是靜態(tài)常量字符串,內(nèi)容是創(chuàng)建索引庫的DSL語句
        request.source(MAPPING_TEMPLATE, XContentType.JSON);
        // 3.發(fā)起請求
        client.indices().create(request, RequestOptions.DEFAULT);
    }
    @BeforeEach
    void setUp() {
        this.client = new RestHighLevelClient(RestClient.builder(
                HttpHost.create("http://192.168.153.131:9200")
        ));
    }
    @AfterEach
    void tearDown() throws IOException {
        this.client.close();
    }
}
4.1.1.代碼解讀

創(chuàng)建索引庫的API如下:

分布式搜索引擎elasticsearch(一),微服務,jenkins,運維

代碼分為三步:

  • 1)創(chuàng)建Request對象。因為是創(chuàng)建索引庫的操作,因此Request是CreateIndexRequest。

  • 2)添加請求參數(shù),其實就是DSL的JSON參數(shù)部分。因為json字符串很長,這里是定義了靜態(tài)字符串常量MAPPING_TEMPLATE,讓代碼看起來更加優(yōu)雅。

  • 3)發(fā)送請求,client.indices()方法的返回值是IndicesClient類型,封裝了所有與索引庫操作有關(guān)的方法。

4.1.2.完整示例

在hotel-demo的cn.itcast.hotel.constants包下,創(chuàng)建一個類,定義mapping映射的JSON字符串常量:

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" +
            "}";
}

在hotel-demo中的HotelIndexTest測試類中,編寫單元測試,實現(xiàn)創(chuàng)建索引:

    @Test
    void testCreateHotelIndex() throws IOException {
        // 1.創(chuàng)建Request對象
        CreateIndexRequest request = new CreateIndexRequest("hotel");
        // 2.請求參數(shù),MAPPING_TEMPLATE是靜態(tài)常量字符串,內(nèi)容是創(chuàng)建索引庫的DSL語句
        request.source(MAPPING_TEMPLATE, XContentType.JSON);
        // 3.發(fā)起請求
        client.indices().create(request, RequestOptions.DEFAULT);
    }

4.2.刪除索引庫

刪除索引庫的DSL語句非常簡單:

DELETE /hotel

與創(chuàng)建索引庫相比:

  • 請求方式從PUT變?yōu)镈ELTE
  • 請求路徑不變
  • 無請求參數(shù)

所以代碼的差異,注意體現(xiàn)在Request對象上。依然是三步走:

  • 1)創(chuàng)建Request對象。這次是DeleteIndexRequest對象
  • 2)準備參數(shù)。這里是無參
  • 3)發(fā)送請求。改用delete方法

在hotel-demo中的HotelIndexTest測試類中,編寫單元測試,實現(xiàn)刪除索引:

    @Test
    void testCreateHotelIndex() throws IOException {
        // 1.創(chuàng)建Request對象
        DeleteIndexRequest request = new DeleteIndexRequest("hotel");
        // 3.發(fā)起請求
        client.indices().delete(request, RequestOptions.DEFAULT);
    }

4.3.判斷索引庫是否存在

判斷索引庫是否存在,本質(zhì)就是查詢,對應的DSL是:

GET /hotel

因此與刪除的Java代碼流程是類似的。依然是三步走:

  • 1)創(chuàng)建Request對象。這次是GetIndexRequest對象
  • 2)準備參數(shù)。這里是無參
  • 3)發(fā)送請求。改用exists方法
    @Test
    void testExistsHotelIndex() throws IOException {
        // 1.創(chuàng)建Request對象
        GetIndexRequest request = new GetIndexRequest("hotel");
        // 2.發(fā)送請求
        boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
        // 3.輸出
        System.err.println(exists ? "索引庫已經(jīng)存在!" : "索引庫不存在!");
    }

4.4.總結(jié)

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

索引庫操作的基本步驟:

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

???????

ES官方提供了各種不同語言的客戶端,用來操作ES。這些客戶端的本質(zhì)就是組裝DSL語句,通過http請求發(fā)送給ES。官方文檔地址:Elasticsearch Clients | Elastic

分布式搜索引擎elasticsearch(一),微服務,jenkins,運維

5?RestClient操作文檔

為了與索引庫操作分離,我們再次參加一個測試類,做兩件事情:

  • 初始化RestHighLevelClient

  • 我們的酒店數(shù)據(jù)在數(shù)據(jù)庫,需要利用IHotelService去查詢,所以注入這個接口

@SpringBootTest
public class HotelDocumentTest {
    @Autowired
    private IHotelService hotelService;

    private RestHighLevelClient client;

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

    @AfterEach
    void tearDown() throws IOException {
        this.client.close();
    }
}

5.1.新增文檔

我們要將數(shù)據(jù)庫的酒店數(shù)據(jù)查詢出來,寫入elasticsearch中。

5.1.1.索引庫實體類

數(shù)據(jù)庫查詢后的結(jié)果是一個Hotel類型的對象。結(jié)構(gòu)如下:

@Data
@TableName("tb_hotel")
public class Hotel {
    @TableId(type = IdType.INPUT)
    private Long id;
    private String name;
    private String address;
    private Integer price;
    private Integer score;
    private String brand;
    private String city;
    private String starName;
    private String business;
    private String longitude;
    private String latitude;
    private String pic;
}

與我們的索引庫結(jié)構(gòu)存在差異:

  • longitude和latitude需要合并為location

因此,我們需要定義一個新的類型,與索引庫結(jié)構(gòu)吻合:

@Data
@NoArgsConstructor
public class HotelDoc {
    private Long id;
    private String name;
    private String address;
    private Integer price;
    private Integer score;
    private String brand;
    private String city;
    private String starName;
    private String business;
    private String location;
    private String pic;

    public HotelDoc(Hotel hotel) {
        this.id = hotel.getId();
        this.name = hotel.getName();
        this.address = hotel.getAddress();
        this.price = hotel.getPrice();
        this.score = hotel.getScore();
        this.brand = hotel.getBrand();
        this.city = hotel.getCity();
        this.starName = hotel.getStarName();
        this.business = hotel.getBusiness();
        this.location = hotel.getLatitude() + ", " + hotel.getLongitude();
        this.pic = hotel.getPic();
    }
}
 

5.1.2.語法說明

新增文檔的DSL語句如下:

POST /{索引庫名}/_doc/1
{
? ? "name": "Jack",
? ? "age": 21
}

對應的java代碼如圖:

分布式搜索引擎elasticsearch(一),微服務,jenkins,運維

可以看到與創(chuàng)建索引庫類似,同樣是三步走:

  • 1)創(chuàng)建Request對象

  • 2)準備請求參數(shù),也就是DSL中的JSON文檔

  • 3)發(fā)送請求

變化的地方在于,這里直接使用client.xxx()的API,不再需要client.indices()了。

5.1.3.完整代碼

我們導入酒店數(shù)據(jù),基本流程一致,但是需要考慮幾點變化:

  • 酒店數(shù)據(jù)來自于數(shù)據(jù)庫,我們需要先查詢出來,得到hotel對象

  • hotel對象需要轉(zhuǎn)為HotelDoc對象

  • HotelDoc需要序列化為json格式

因此,代碼整體步驟如下:

  • 1)根據(jù)id查詢酒店數(shù)據(jù)Hotel

  • 2)將Hotel封裝為HotelDoc

  • 3)將HotelDoc序列化為JSON

  • 4)創(chuàng)建IndexRequest,指定索引庫名和id

  • 5)準備請求參數(shù),也就是JSON文檔

  • 6)發(fā)送請求

在hotel-demo的HotelDocumentTest測試類中,編寫單元測試:

@Test
void testAddDocument() throws IOException {
    // 1.根據(jù)id查詢酒店數(shù)據(jù)
    Hotel hotel = hotelService.getById(61083L);
    // 2.轉(zhuǎn)換為文檔類型
    HotelDoc hotelDoc = new HotelDoc(hotel);
    // 3.將HotelDoc轉(zhuǎn)json
    String json = JSON.toJSONString(hotelDoc);

    // 1.準備Request對象
    IndexRequest request = new IndexRequest("hotel").id(hotelDoc.getId().toString());
    // 2.準備Json文檔
    request.source(json, XContentType.JSON);
    // 3.發(fā)送請求
    client.index(request, RequestOptions.DEFAULT);
}
 

5.2.查詢文檔

5.2.1.語法說明

查詢的DSL語句如下:

GET /hotel/_doc/{id}

非常簡單,因此代碼大概分兩步:

  • 準備Request對象

  • 發(fā)送請求

不過查詢的目的是得到結(jié)果,解析為HotelDoc,因此難點是結(jié)果的解析。完整代碼如下:

分布式搜索引擎elasticsearch(一),微服務,jenkins,運維

可以看到,結(jié)果是一個JSON,其中文檔放在一個_source屬性中,因此解析就是拿到_source,反序列化為Java對象即可。

與之前類似,也是三步走:

  • 1)準備Request對象。這次是查詢,所以是GetRequest

  • 2)發(fā)送請求,得到結(jié)果。因為是查詢,這里調(diào)用client.get()方法

  • 3)解析結(jié)果,就是對JSON做反序列化

5.2.2.完整代碼

在hotel-demo的HotelDocumentTest測試類中,編寫單元測試:

    @Test
    void testGetDocumentById() throws IOException {
        // 1.準備Request
        GetRequest request = new GetRequest("hotel", "61083");
        // 2.發(fā)送請求,得到響應
        GetResponse response = client.get(request, RequestOptions.DEFAULT);
        // 3.解析響應結(jié)果
        String json = response.getSourceAsString();

        HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
        System.out.println(hotelDoc);
    }
 

5.3.刪除文檔

刪除的DSL為是這樣的:

DELETE /hotel/_doc/{id}

與查詢相比,僅僅是請求方式從DELETE變成GET,可以想象Java代碼應該依然是三步走:

  • 1)準備Request對象,因為是刪除,這次是DeleteRequest對象。要指定索引庫名和id
  • 2)準備參數(shù),無參
  • 3)發(fā)送請求。因為是刪除,所以是client.delete()方法

在hotel-demo的HotelDocumentTest測試類中,編寫單元測試:

    @Test
    void testDeleteDocument() throws IOException {
        // 1.準備Request
        DeleteRequest request = new DeleteRequest("hotel", "61083");
        // 2.發(fā)送請求
        client.delete(request, RequestOptions.DEFAULT);
    }

5.4.修改文檔

5.4.1.語法說明

修改我們講過兩種方式:

  • 全量修改:本質(zhì)是先根據(jù)id刪除,再新增
  • 增量修改:修改文檔中的指定字段值

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

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

這里不再贅述,我們主要關(guān)注增量修改。

代碼示例如圖:

分布式搜索引擎elasticsearch(一),微服務,jenkins,運維

與之前類似,也是三步走:

  • 1)準備Request對象。這次是修改,所以是UpdateRequest
  • 2)準備參數(shù)。也就是JSON文檔,里面包含要修改的字段
  • 3)更新文檔。這里調(diào)用client.update()方法

5.4.2.完整代碼

在hotel-demo的HotelDocumentTest測試類中,編寫單元測試:

@Test
void testUpdateDocument() throws IOException {
    // 1.準備Request
    UpdateRequest request = new UpdateRequest("hotel", "61083");
    // 2.準備請求參數(shù)
    request.doc(
        "price", "952",
        "starName", "四鉆"
    );
    // 3.發(fā)送請求
    client.update(request, RequestOptions.DEFAULT);
}
 

5.5.批量導入文檔

案例需求:利用BulkRequest批量將數(shù)據(jù)庫數(shù)據(jù)導入到索引庫中。

步驟如下:

  • 利用mybatis-plus查詢酒店數(shù)據(jù)
  • 將查詢到的酒店數(shù)據(jù)(Hotel)轉(zhuǎn)換為文檔類型數(shù)據(jù)(HotelDoc)
  • 利用JavaRestClient中的BulkRequest批處理,實現(xiàn)批量新增文檔

5.5.1.語法說明

批量處理BulkRequest,其本質(zhì)就是將多個普通的CRUD請求組合在一起發(fā)送。

其中提供了一個add方法,用來添加其他請求:

分布式搜索引擎elasticsearch(一),微服務,jenkins,運維

可以看到,能添加的請求包括:

  • IndexRequest,也就是新增
  • UpdateRequest,也就是修改
  • DeleteRequest,也就是刪除

因此Bulk中添加了多個IndexRequest,就是批量新增功能了。示例:

分布式搜索引擎elasticsearch(一),微服務,jenkins,運維

其實還是三步走:

  • 1)創(chuàng)建Request對象。這里是BulkRequest
  • 2)準備參數(shù)。批處理的參數(shù),就是其它Request對象,這里就是多個IndexRequest
  • 3)發(fā)起請求。這里是批處理,調(diào)用的方法為client.bulk()方法

我們在導入酒店數(shù)據(jù)時,將上述代碼改造成for循環(huán)處理即可。

5.5.2.完整代碼

在hotel-demo的HotelDocumentTest測試類中,編寫單元測試:

@Test
void testBulkRequest() throws IOException {
    // 批量查詢酒店數(shù)據(jù)
    List<Hotel> hotels = hotelService.list();

    // 1.創(chuàng)建Request
    BulkRequest request = new BulkRequest();
    // 2.準備參數(shù),添加多個新增的Request
    for (Hotel hotel : hotels) {
        // 2.1.轉(zhuǎn)換為文檔類型HotelDoc
        HotelDoc hotelDoc = new HotelDoc(hotel);
        // 2.2.創(chuàng)建新增文檔的Request對象
        request.add(new IndexRequest("hotel")
                    .id(hotelDoc.getId().toString())
                    .source(JSON.toJSONString(hotelDoc), XContentType.JSON));
    }
    // 3.發(fā)送請求
    client.bulk(request, RequestOptions.DEFAULT);
}
 

5.6.小結(jié)

文檔操作的基本步驟:文章來源地址http://www.zghlxwxcb.cn/news/detail-785258.html

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

到了這里,關(guān)于分布式搜索引擎elasticsearch(一)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

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

領(lǐng)支付寶紅包贊助服務器費用

相關(guān)文章

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

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

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

    2024年03月20日
    瀏覽(30)
  • 分布式搜索引擎elasticsearch(一)

    分布式搜索引擎elasticsearch(一)

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

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

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

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

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

    Elasticsearch 分布式搜索引擎 速學

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

    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 部署單點es 創(chuàng)建網(wǎng)絡 因為我們還需要部署kibana容器,因此需要讓es和kibana容器互聯(lián)。這里先創(chuàng)建一個網(wǎng)絡: 加載鏡像

    2024年01月17日
    瀏覽(34)
  • 分布式搜索引擎ElasticSearch——深入elasticSearch

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

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

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

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

    2024年02月05日
    瀏覽(31)
  • 微服務---分布式搜索引擎 elasticsearch基礎(chǔ)

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

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

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

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

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

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

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

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

    2024年01月25日
    瀏覽(54)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

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

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包