SpringBoot系列之Elasticsearch極速入門與實際教程

smileNicky發表於2020-07-16

@

一、什麼Elasticsearch?

在這裡插入圖片描述
Elasticsearch是一款開源的分散式搜尋引擎,基於 JSON 開發而來,具有 RESTful 風格,基於 Apache Lucene 的基礎上開發而成的

引用官網的說法:
在這裡插入圖片描述

引用官網的說法,Elasticsearch的用途:

Elasticsearch 的用途是什麼?

  • 應用程式搜尋
  • 網站搜尋
  • 企業搜尋
  • 日誌處理和分析
  • 基礎設施指標和容器監測
  • 應用程式效能監測
  • 地理空間資料分析和視覺化
  • 安全分析
  • 業務分析

二、Elasticsearch安裝部署

2.1 Elasticsearch安裝環境準備

環境準備:

  • elasticsearch7.2.0
  • docker環境

相關工具軟體:

  • VM VisualBox
  • xShell,Xftp

docker入門部落格可以參考我的docker系統部落格專欄:連結

2.2 Docker環境安裝Elasticsearch

docker映象搜尋:

docker search elasticsearch

需要加上版本,不加版本預設是laster(最新)版本,貌似沒提供laster版本

docker pull elasticsearch:7.2.0

檢視所有映象:

docker images

在這裡插入圖片描述
執行docker映象:

  • -p 隱射埠
  • -e 設定引數,discovery.type=single-node,設定單節點,ES_JAVA_OPTS="-Xms256m -Xmx256m",設定JVM引數
  • -d 後臺執行
  • --name 節點名稱
docker run -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms256m -Xmx256m" -d --name ES01 elasticsearch:7.2.0

linux內用curl訪問:

curl http://localhost:9200

在這裡插入圖片描述
瀏覽器直接訪問也是可以的:http://your_ip_addr:9200
在這裡插入圖片描述
ps:詳情可以參考官方文件:Install Elasticsearch with Docker

2.3 Elasticsearch目錄結構介紹

在這裡插入圖片描述

目錄 配置檔案 描述
bin 指令碼檔案,包括啟動 Elasticsearch、安裝外掛,執行統計資料等。
config elasticsearch.yml 叢集配置檔案
JDK Java 執行環境
data path.data 資料檔案
lib Java 類庫
logs path.logs 日誌檔案
modules 包含所有 ES 模組
plugins 包含所有已安裝外掛

ps:Elasticsearch也有linux版和window版,本部落格不做介紹

2.4 Elasticsearch cat命令使用

cat 命令可以幫助開發者快速查詢 Elasticsearch 的相關資訊

  • _cat 引數
    _cat 引數可以檢視支援的命令
[root@localhost ~]#  curl localhost:9200/_cat
=^.^=
/_cat/allocation
/_cat/shards
/_cat/shards/{index}
/_cat/master
/_cat/nodes
/_cat/tasks
/_cat/indices
/_cat/indices/{index}
/_cat/segments
/_cat/segments/{index}
/_cat/count
/_cat/count/{index}
/_cat/recovery
/_cat/recovery/{index}
/_cat/health
/_cat/pending_tasks
/_cat/aliases
/_cat/aliases/{alias}
/_cat/thread_pool
/_cat/thread_pool/{thread_pools}
/_cat/plugins
/_cat/fielddata
/_cat/fielddata/{fields}
/_cat/nodeattrs
/_cat/repositories
/_cat/snapshots/{repository}
/_cat/templates

  • ?v 引數
    ?v 引數,來顯示詳細的資訊
[root@localhost ~]# curl localhost:9200/_cat/master?v
id                     host       ip         node
8x63m-D8Q2CP4xRbq7rEFA 172.17.0.2 172.17.0.2 7610b4e6e11b
  • 其它常用命令:

    • 檢視所有外掛:http://your_ip_addr:9200/_cat/plugins?v
    • 檢視所有索引:http://your_ip_addr:9200/_cat/indices?v
    • 對ES進行健康檢查:http://your_ip_addr:9200/_cat/health?v
    • 檢視當前的磁碟佔用率:http://your_ip_addr:9200/_cat/allocation?v
  • help引數
    help 引數,來輸出可以顯示的列

[root@localhost ~]# curl localhost:9200/_cat/master?help
id   |   | node id    
host | h | host name  
ip   |   | ip address 
node | n | node name  
  • h引數
    h 引數,可以指定輸出的欄位
[root@localhost ~]# curl localhost:9200/_cat/master?h=host,ip,node
172.17.0.2 172.17.0.2 7610b4e6e11b

三、Elasticsearch基本概念

3.1 索引(Index)

ElasticSearch把資料存放到一個或者多個索引(indices)中。如果用關係型資料庫模型對比,索引(index)的地位與資料庫例項(database)相當,Elastic 資料管理的頂層單位就叫做 Index(索引)。它是單個資料庫的同義詞。每個 Index (即資料庫)的名字必須是小寫。

3.2 文件型別(Type)

如果一個索引(index)有多個文件的情況,可以根據型別(type)進行歸類,如果用關係型資料庫模型對比,索引(index)的地位與資料表(table)相當。文件型別使得同一個索引中在儲存結構不同文件時,只需要依據文件型別就可以找到對應的引數對映(Mapping)資訊

3.3 文件(Document)

文件(Document)由一個或者多個域(Field)組成,每個域(Field)由一個域名(此域名非彼域名)和一個或者多個值組成(有多個值的值稱為多值域(multi-valued))

3.4 屬性/域(Field)

如果用關係型資料庫模型對比,域(Field)的地位與資料庫模型中的列(column)相當

3.5 節點(Node)

每臺伺服器可以執行多個 Elastic 例項,單獨一個ElasticSearch伺服器例項稱為一個節點

3.6 叢集(Cluster)

叢集是多個ElasticSearch節點的集合,Elastic 本質上是一個分散式資料庫,允許多臺伺服器協同工作,每臺伺服器可以執行多個 Elastic 例項。

3.7 分片索引(Shard)

叢集能夠儲存超出單機容量的資訊。為了實現這種需求,ElasticSearch把資料分發到多個儲存Lucene索引的物理機上。這些Lucene索引稱為分片索引,這個分發的過程稱為索引分片(Sharding)。在ElasticSearch叢集中,索引分片(Sharding)是自動完成的,而且所有分片索引(Shard)是作為一個整體呈現給使用者的

3.8 索引副本(Replica)

索引副本(Replica)機制的的思路很簡單:為索引分片建立一份新的拷貝,它可以像原來的主分片一樣處理使用者搜尋請求

3.9 閘道器(Gateway)

在執行的過程中,ElasticSearch會收集叢集的狀態、索引的引數等資訊。這些資料被儲存在Gateway中。

下面用一張表格簡單記錄對比:

Elasticsearch 關聯式資料庫
索引 (Index) 資料庫(Database)
型別(Type) 資料表(Table)
文件(Document) 表中記錄/資料行(Row)
域(Field) 資料列(Column)
引數對映(Mapping) 模式(Schema)

一個 ElasticSearch 叢集可以 包含多個 索引 ,相應的每個索引可以包含多
個 型別 。 這些不同的型別儲存著多個 文件 ,每個文件又有 多個域

四、Elasticsearch基本使用

4.1 RESTFul API

Elasticsearch是支援RESTFul API格式的,所以先補充一些RESTFul API知識:

  • GET 請求:獲取伺服器中的物件

    • 相當於SQL的Select命令
    • GET /emps:列出所有員工資訊
  • POST 請求:在伺服器上更新物件

    • 相當於SQL的Update命令
    • POST /emps/ID:更新指定的員工資訊
  • PUT 請求:在伺服器上建立物件

    • 相當於SQL的Create命令
    • PUT /emps/ID:新建一個員工資訊  
  • DELETE 請求:刪除伺服器中的物件

    • 相當於SQL的Delete命令
    • DELETE /blogs/ID:刪除指定的部落格
  • HEAD 請求:僅僅用於獲取物件的基礎資訊

4.2 查詢所有索引

查詢所有的索引:

curl -X GET 'http://localhost:9200/_cat/indices?v'

在這裡插入圖片描述

ok,進行索引實踐,建議以官網對應版本文件為準,本部落格參考7.2版本的,連結:https://www.elastic.co/guide/en/elasticsearch/reference/7.2/docs.html

4.3 Elastic索引建立

  • PUT,建立索引:
[root@localhost ~]# curl -H "Content-Type:application/json" -X PUT localhost:9200/company/employees/1 -d '{"id" :1,"name":"admin","password":"123"}'

返回json:

{
    "_index":"company",
    "_type":"employees",
    "_id":"1",
    "_version":1,
    "result":"created",
    "_shards":{
        "total":2,
        "successful":1,
        "failed":0
    },
    "_seq_no":0,
    "_primary_term":1
}

4.4 Elastic索引查詢

  • GET,查詢索引:
[root@localhost ~]# curl -X GET localhost:9200/company/employees/1?pretty=true
{
  "_index" : "company",
  "_type" : "employees",
  "_id" : "1",
  "_version" : 1,
  "_seq_no" : 0,
  "_primary_term" : 1,
  "found" : true,
  "_source" : {
    "id":1,
    "name":"admin",
    "password":"123"
	}
}

4.5 Elastic索引刪除

  • DELETE,刪除索引:
[root@localhost ~]# curl -X DELETE localhost:9200/company/employees/1
{
    "_index":"company",
    "_type":"employees",
    "_id":"1",
    "_version":2,
    "result":"deleted",
    "_shards":{
        "total":2,
        "successful":1,
        "failed":0
    },
    "_seq_no":1,
    "_primary_term":1
}

4.6 Elastic索引更新

  • POST,更新索引:
curl -H "Content-Type:application/json" -X POST localhost:9200/company/employees/1 -d '{"id" :1,"name":"admin","password":"111"}'
{
    "_index":"company",
    "_type":"employees",
    "_id":"1",
    "_version":2,
    "result":"updated",
    "_shards":{
        "total":2,
        "successful":1,
        "failed":0
    },
    "_seq_no":3,
    "_primary_term":1
}

五、Spring Data Elasticsearch

5.1 開發環境準備

實驗環境:

  • SpringBoot2.2.1
  • Elasticsearch7.2.0

maven配置:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.1.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example.springboot</groupId>
    <artifactId>springboot-elasticsearch</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springboot-elasticsearch</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

2.2.1版本,只要指定uris,舊版本要配置cluster-nodes和cluster-name

spring:
  elasticsearch:
    rest:
      uris: 192.168.7.96:9200

5.2 @Document使用

指定index和type

package com.example.springboot.elasticsearch.bean;

import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;

import java.io.Serializable;

/**
 * <pre>
 *  Employee
 * </pre>
 *
 * <pre>
 * @author mazq
 * 修改記錄
 *    修改後版本:     修改人:  修改日期: 2020/07/16 17:02  修改內容:
 * </pre>
 */
@Data
@Document(indexName = "company",type = "employees",shards = 5,replicas = 1)
public class Employee implements Serializable {
    @Id
    private Long id;
    @Field(type = FieldType.Text)
    private String name;
    @Field(type = FieldType.Text)
    private String password;

    @Override
    public String toString() {
        return "Employee{" +
                "id='" + id + '\'' +
                ", name='" + name + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

5.3 ElasticsearchRepository

實現ElasticsearchRepository

package com.example.springboot.elasticsearch.repository;

import com.example.springboot.elasticsearch.bean.Employee;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Repository;

/**
 * <pre>
 *  EmployeeRepository
 * </pre>
 *
 * <pre>
 * @author mazq
 * 修改記錄
 *    修改後版本:     修改人:  修改日期: 2020/07/16 17:24  修改內容:
 * </pre>
 */
@Repository
public interface EmployeeRepository extends ElasticsearchRepository<Employee,Long>{

}

5.4 Junit 測試Elasticsearch

新增索引:

@Autowired
    EmployeeRepository employeeRepository;
    
    @Test
    void createIndex(){
        Employee employee = new Employee();
        employee.setId(2L);
        employee.setName("sys");
        employee.setPassword("123");
        employeeRepository.save(employee);
    }

在這裡插入圖片描述
查詢索引:

  @Autowired
    EmployeeRepository employeeRepository;
    @Test
    void selectIndex(){
        Optional<Employee> employee = employeeRepository.findById(2L);
        System.out.println(employee.get().toString());
    }

在這裡插入圖片描述

程式碼例子下載:code download

相關文章