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
}
}
}
}
}