1. 程式人生 > 其它 >ElasticSearch入門

ElasticSearch入門

ElasticSearch入門

一、ElasticSearch介紹

1、概述

ElasticSearch是基於Apache組織的Lucene開源搜尋引擎開發的一個搜尋引擎。

ElasticSearch編寫的目的是使用簡單的RESTfulAPI來實現全文搜尋並摒棄Lucene的複雜操作。

除此之外,ElasticSearch還提供了:

(1)分散式的檔案儲存,存入的資料中每個欄位都經過索引並可以通過API來搜尋。

(2)實時分析的分散式搜尋引擎。

(3)可以擴充套件到上百臺的伺服器上,處理海量級別的結構化或非結構化資料。

2、重要概念

(1)接近實時(NRT)

ElasticSearch得於Lucene的支援,它是一個趨近於實時的搜尋引擎。它從索引一個文件到能通過搜尋API搜尋到這個文件,僅僅有一個忽略不計的延遲(1秒左右)。

(2)叢集(Cluster)

由於ElasticSearch能支援海量資料搜尋,所以叢集是必要的。使用者可以通過配置一個叢集標識(預設是ElasticSearch),讓其他節點加入這個叢集,實現比如資料的分離和搜尋的引導。

(3)節點(Node)

節點就是叢集中的一個伺服器,它作為叢集的一部分,可以通過主備來實現主節點和備用節點,並存儲使用者的資料。如果在所有ElasticSearch伺服器中沒有執行任何一個節點,那麼它會預設建立並加入一個ElasticSearch叢集。

(4)索引(Index)

一個索引就是一個文件的集合,可以理解成關係型資料庫中Database的概念,一個索引由它的名字(必須是小寫字母)來作為標識,後續可以通過這個索引對文件進行增刪改查的操作。

倒排索引:通過關鍵字來查詢,這是ElasticSearch中全文檢索速度快的原因。

正排(正向)索引:在關係型資料庫中使用id等欄位作為索引。

(5)型別(Type)

一個型別是一個索引的子類,多個型別組成了一個索引。型別主要存有一些擁有共同欄位的文件。可以理解成關係型資料庫中Table的概念。

(6)文件(Document)

一個文件是ElasticSearch中可以被搜尋到的基礎資訊。在ElasticSearch中主要是使用JSON的格式來表示,你可以存有一個使用者的文件,他的訂單文件等。文件中除了這些資料外,還包括有_index、_type和_id欄位。

(7)分片(Shards)

一個索引中能夠儲存超過某個節點硬體限制的資料,前提是對其進行了分片操作。比如一個索引佔用了超過1TB的空間,但是在叢集中沒有任何一個節點有1TB的容量,此時就會對這個索引進行分片操作。當然,這也是為了能夠將搜尋的速度進行最優操作。

在建立一個索引的時候,可以指定分片的數量,此時由於定義了分片操作,這個索引可以在叢集中的任何節點上找到。

在分片中,能夠實現這兩個重要的功能:

·可以通過分片來擴充套件某個索引的容量,以及實現資料的分割。

·實現分片後可以在叢集中進行分散式/並行的操作,進而提高叢集的處理能力。

(8)複製(Replicas)

在任何一個系統中,出現宕機等問題的可能性隨時都會發生,ElasticSearch也不例外。

ElasticSearch提供了一種索引備份的機制,它允許使用者建立分片的複製分片。

複製分片不會和原分片在同一個節點上,因為如果在叢集中,某個節點發生宕機,如果同時存在於同一個節點上的話,此時這個索引備份機制是沒有意義的。

在索引建立後,使用者可以隨時改變複製數量,但不能改變分片的數量,因為改變分片的數量時是會進行資料的重新切割,而複製則不會對分片造成任何影響。

預設情況下,ElasticSearch的每個索引會被設定成5個分片和1個複製索引,當然這是在有至少兩個節點的前提下,如果只有一個節點,那麼分片沒有任何意義。

二、下載與啟動

1、前置條件

環境說明:

伺服器:阿里雲輕量應用伺服器

作業系統:CentOS8.2

記憶體:2G

ElasticSearch版本:7.15.1

執行ElasticSearch需要在伺服器上安裝jdk

yum install -y java-1.8.0-openjdk java-1.8.0-openjdk-devel

2、下載tar.gz檔案

wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.15.1-linux-x86_64.tar.gz

3、解壓

tar -vxf elasticsearch-7.15.1-linux-x86_64.tar.gz

4、ElasticSearch目錄說明

目錄 配置檔案 描述
bin 放置指令碼檔案,如啟動指令碼 ElasticSearch, 外掛安裝指令碼等。
config elasticserch.yml ElasticSearch配置檔案,如叢集配置、jvm 配置等。
jdk java 執行環境
data path.data 資料持久化檔案
lib 依賴的相關類庫
logs path.log 日誌檔案
modulElasticSearch 包含的所有 ElasticSearch 模組
plugins 包含的所有已安裝的外掛

5、新使用者配置

由於ElasticSearch不能使用root使用者啟動,所以需要新建一個elastic使用者

CentOS8的新增使用者命令

adduser elastic

給elastic使用者賦予許可權(使用root賬號)

chown -R elastic:elastic /software/elasticsearch-7.15.1

6、啟動

使用elastic使用者,進入對應資料夾的bin目錄下

使用命令啟動,-d是在後臺執行

./elasticsearch -d

7、驗證

使用命令

curl localhost:9200

最終控制檯顯示以下內容就成功啟動了

{
  "name" : "iZax8lw98s1xu9Z",
  "cluster_name" : "elasticsearch",
  "cluster_uuid" : "D-A_yUfpSrmgxThbKSox6Q",
  "version" : {
    "number" : "7.15.1",
    "build_flavor" : "default",
    "build_type" : "tar",
    "build_hash" : "83c34f456ae29d60e94d886e455e6a3409bba9ed",
    "build_date" : "2021-10-07T21:56:19.031608185Z",
    "build_snapshot" : false,
    "lucene_version" : "8.9.0",
    "minimum_wire_compatibility_version" : "6.8.0",
    "minimum_index_compatibility_version" : "6.0.0-beta1"
  },
  "tagline" : "You Know, for Search"
}

8、注意事項

(1)遠端訪問需要修改elasticsearch.yml中的network.host屬性,將其改成0.0.0.0

(2)報錯提示

bootstrap check failure [1] of [3]: max file dElasticSearchcriptors [4096] for elasticsearch procElasticSearchs is too low, increase to at least [65535]  

需要開啟/etc/security/limits.conf檔案

在結尾增加以下內容,其中elastic為建立的新使用者

elastic soft nofile 65536
elastic hard nofile 65536

(3)報錯提示

bootstrap check failure [2] of [3]: max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]

需要開啟/etc/sysctl.conf檔案

在結尾增加以下內容

vm.max_map_count=262144

(4)報錯提示

bootstrap check failure [3] of [3]: the default discovery settings are unsuitable for production use; at least one of [discovery.seed_hosts, discovery.seed_providers, cluster.initial_master_nodElasticSearch] must be configured

需要進行對discovery.seed_hosts, discovery.seed_providers, cluster.initial_master_nodElasticSearch其中一個的配置

配置內容如下

    # 啟動地址,如果不配置,只能本地訪問
    network.host: 0.0.0.0
    # 節點名稱
    node.name: node1
    # 初始化時master節點的選舉列表
    cluster.initial_master_nodElasticSearch: [ "node1" ]
    # 叢集名稱
    cluster.name: elasticsearch
    # 對外提供服務的埠
    http.port: 9200
    # 內部服務埠
    transport.port: 9300    
    # 跨域支援
    http.cors.enabled: true
    # 跨域訪問允許的域名地址(正則)
    http.cors.allow-origin: /.*/

三、ElasticSearch RESTful API的使用

ElasticSearch提供了非常多的基於HTTP協議的RESTful API,只需要向ElasticSearch傳送RESR請求,就可以實現它提供的一系列功能。

目前的資料中大部分是使用的Linux的curl命令來發送請求,我使用Postman來發送,因為它圖形化,並且相對於命令也更容易操作

1、健康檢查

健康檢查主要用來檢視叢集的執行情況,由於只有一個節點,所以暫時不用瞭解太多。

URL格式(GET)

/_cat/health?v

其中?v主要用來顯示欄位

最終效果如圖所示

其中,status為green表示正常,其他的還有yellow(所有資料都可用但複製分片不可用)、red(部分資料不可用)。

2、獲取叢集中節點列表

URL格式(GET)

/_cat/nodes?v

從下圖可以看到叢集中只有一個名為node1的節點。

3、建立索引

URL格式(PUT)

/索引名

acknowledged為true表示索引建立成功,由於預設是進行了分片操作的,所以shards_acknowledged也為true,index則表示索引名稱。

4、列出索引

URL格式(GET)

/_cat/indices?v

節點中有一個預設的索引,另外有一個index1的索引,index1索引的health為yellow,是因為現在節點只有一個,不能對分片進行復制,等到新增第二個節點的時候就會恢復成green。

5、建立文件

建立了索引之後就可以把文件存入到ElasticSearch中了。

URL格式(PUT/POST)

/索引名/_doc/文件id
/索引名/_create/文件id

ps:由於ElasticSearch在6.X版本之後就要逐步移除型別(Type)的概念,所以型別就不寫上去了,直接用_doc代替。

需要向這個URL傳送一個PUT請求,並在請求中帶入一個JSON字串,此時ElasticSearch會返回一個存入的狀態,其中各個欄位表示如表格所示

欄位 含義
_index 索引,用於表示當前文件是在哪個索引中
_type 型別,用於表示當前文件是在哪個型別中
_id id,文件的id
_version 版本,文件的版本,如果對其進行了操作,那麼這個值會增加
result 結果,有created,updated,deleted等情況,表示新增,更新,刪除
_shards 分片情況
_seq_no 索引的序列號
_primary_term 和_seq_no組合使用

當索引不存在時也能存入文件,當索引不存在時,會自動建立索引

當文件id不存在時也能建立文件,此時id會由系統自動生成,但需要傳送POST請求而不是PUT

6、查詢文件

URL格式(GET)

/索引名/_doc/文件id

其中found欄位為true表示找到了id為1的文件,_source是文件的具體內容。

7、查詢索引下的所有文件

URL格式(GET)

/索引名/_search

ps:這種方式只能查詢到10條,如果要查詢到所有的資料,可以使用分頁的查詢條件。

其中各個欄位的說明:

欄位 含義
took ElasticSearch搜尋所使用的時間(毫秒)
timed_out 是否超時
_shards 搜尋的分片資訊
hits 搜尋結果
hits.total 搜尋命中資訊
hits.hits 搜尋結果
hits._score/max_score score是判斷搜尋條件匹配程度的指標,分數越高文件和搜尋條件越相關

8、更新文件

URL格式(POST/PUT)

1、/索引名/_update/更新的文件id(POST)
2、/索引名/_doc/更新的文件id(PUT)

引數格式

1、
{
    "doc":{
        //更新的內容
    }
}
2、
{
    //更新的內容
}

更新文件和建立文件的方式是一樣的,如果建立的文件已存在,那麼就會自動更新它。

如果文件不存在則自動建立。(僅限_doc的方式)

此時result的值是updated,_version的值也增加。

9、刪除文件

URL格式(DELETE)

/索引名/_doc/刪除的文件id

此時result的值是deleted,_version也變成了3.

10、刪除索引

URL格式(DELETE)

/索引名

執行後會返回true,表示已經刪除成功。

這時再查詢索引,已經沒有了。

11、搜尋文件

(1)按條件搜尋文件

URL格式(GET)

/索引名/_search

引數格式

{
    "query":{
        "match":{
            //搜尋條件:key:value
            //match表示匹配,可以替換成match_all,表示查詢所有
        }
    }
}

(2)分頁查詢

引數格式

{
    "query":{
        "match":{
            //搜尋條件
        }
    },
    "from":0,
    "size":20
    //表示從0開始搜尋,返回20條資料
}

(3)排序

引數格式

{
    "query":{
        "match_all":{//查詢所有
        }
    },
    "sort":{
        "age":{//表示按年齡排序
            "order":"asc"//表示排序方式是升序
        }
    }
}

(4)資料過濾

引數格式

{
    "query":{
        "bool":{
            "must":{
                "match":{
                    "name":"lxy10"
                }
            },
            "filter":{
                "range":{
                    "age":{
                        "gt":30
                    }
                }
            }
        }
    },
    "sort":{
        "age":{
            "order":"asc"
        }
    }
}

上面查詢條件表示name是"lxy10",並且年齡大於30,最後按照年齡的升序排序。

12、全文檢索

(1)全文檢索

全文檢索時會將使用者輸入的字串給拆分出來,然後去倒排索引裡面一一匹配,只要能匹配到某一個字或單詞,那麼就將結果返回。

URL格式(GET)

/索引名/_search

引數格式

{
    "query":{
        "match":{
            //搜尋條件,可以是完整的名稱,也可以是一個字或單詞
        }
    }
}

(2)短語搜尋

和全文檢索相反,短語檢索是必須要完全匹配才能將結果返回。

引數格式

{
    "query":{
        "match_phrase":{
            //搜尋條件,必須和結果中包含了一樣的才會返回
        }
    }
}

(3)高亮搜尋結果

高亮搜尋結果主要是將查詢的條件給高亮出來,效果參考百度搜索。

{
    "query":{
        "match":{
            //搜尋條件
        }
    },
    "highlight":{
        "fields":{
            //高亮欄位
        }
    }
}

13、聚合

使用聚合檢索可以對結果進行統計,如求平均或求和等運算。

在進行聚合檢索之前,需要對文件的屬性進行調整。

(1)文件屬性調整

URL格式(POST)

/索引名/_mapping

引數格式

{
    "properties":{
        "name":{
            "type":"text",//text表示這個屬效能夠被分詞
            "index":true,//true表示加入索引
            "fielddata":true//儲存的資料結構是fielddata
        },
        "category":{
            "type":"keyword"
        },
        "price":{
            "type":"long",
            "index":true
        }
    }
}

ps:這個操作比較類似資料表中定義資料表結構。

(2)統計每個name下的數量

引數格式

{
    "aggs":{
        "phone_count":{
            "terms":{
                "field":"name"//後面跟文件的屬性
            }
        }
    },
    "size":0//如果不加這個會把檢索的結果也返回
}

(3)統計名稱中包含X並計算每個name下的數量

引數格式

{
    "aggs":{
        "phone_count":{
            "terms":{
                "field":"name"
            }
        }
    },
    "size":0,
    "query":{
        "match":{
            "name":"X"
        }
    }
}

(4)統計商品的平均價格

引數格式

{
    "aggs":{
        "phone_avg":{
            "avg":{
                "field":"price"
            }
        }
    },
    "size":0
}

(5)檢索某個範圍內的商品數量

引數格式

{
    "aggs":{
        "phone_range":{
            "range":{
                "field":"price",
                "ranges":{
                    "from":0,
                    "to":1000
                }
            }
        }
    }
}