Elasticsearch 開箱指南
- 2020 年 2 月 19 日
- 筆記

內容概要
- ES 基礎介紹,重點是其中的核心概念。
- 基礎 API 實踐操作。
1. 基礎介紹
Elasticsearch (ES) 是一個資料庫,提供了分散式的、准實時搜索和分析。
基於 Apache Lucene,可以操作結構化數據、非結構化數據、數字類型數據、地理空間數據。
數據存儲使用鬆散結構的 JSON 文檔。
主要特性
- 輕量快速的全文搜索。
- 安全分析和基礎設施監控。
- 支援海量規模,數千台伺服器、PB級數據量。
- 可以集成可視化數據分析工具,用於例如應用性能分析、日誌監控、基礎設施度量指標監控。
- 可以用於機器學習,對數據實時進行自動化模型處理。
核心概念

- Index 索引
關係資料庫中的表,存儲文檔。
6.0.0 版本之前,一個索引中可以存放不同類型的文檔,例如 Car 和 Bike 這2種文檔可以在一個索引中。
6.0.0 版本之後,不可以了,需要為每種類型的文檔建立不同的索引。
- Documents 文檔
關係資料庫中的 行。
每個文檔有一個唯一 _id。
- Fields 欄位
關係資料庫中的 列。
- 數據類型
1)字元串
有2種類型:text 和 keyword。
text 用戶存儲產品描述、文章內容之類的文本,可以根據關鍵字在其中查找。
ES 會把內容解析成一個字元串列表,然後創建倒排索引,描述每個單詞都在哪些文檔中出現了。
例如一個文檔有一個欄位 「Description」,值為 「This phone has dual sim capability」。
這個值會被解析為一個列表:
[「this」, 「phone」, 「has」, 「dual」, 「sim」, 「capability」]
倒排索引中,會指出每個詞所在的文檔列表,如:
「this」 -> doc_1,doc_3
Keyword 用於存儲用戶名、郵件地址、郵編這類的明確的內容。
這類內容不會被分割解析,適用於精確匹配。
2)數字
存儲例如標識碼、百分比、電話號等。
支援:long, integer, short, byte, double, float。
3)日期
形式包括:「2015/01/01 12:10:30」 此類的字元串、微秒級 long 型數字、秒級 integer 型數字。
內部使用 UTC long 型存儲。
4)布爾
5)IP
6)嵌入式
一個屬性可以是一個 JSON 數組。
例如:
{ "name":"ABC United", "homeGround":"Old Trafford", "players":[ { "firstName":"James", "lastName":"Cohen", "position":"Goal Keeper" }, { "firstName":"Paul", "lastName":"Pogba", "position":"Midfielder" } ] }對於嵌入類型,每個數組對象都會被作為一個隱藏文檔進行索引。
7)多類型
例如有一個欄位 「student_name」,我們希望可以通過部分匹配的方式進行查找,也希望通過完全匹配的方式查找。
這就相當於同時有2種類型:text和 keyword。
可以這樣設置:
{ "student_name":{ "type":"text", "fields":{ "keyword":{ "type":"keyword" } } } }- Mapping
用於定義一個索引的 schema。
定義索引中有哪些欄位、欄位類型,配置類型相關的元數據。
- Setting
通過 Setting 可以自定義一些索引的行為,還允許我們自定義分析器和標準化器,以分析索引的不同文本欄位。
重要的 Setting 例如:
1)number_of_shards:定義索引分片數量,默認為 1。
2)number_of_replicas:定義分片的副本數量,默認 1。
3)refresh_interval:用於指定文檔索引的時間與可供搜索的時間之間的間隔,默認 1秒。
- Shard 分片
一個分片是一個 Lucene 實例,是一個被 ES 自動管理的工作單元。
我們只需要指定分片及其副本的數量,無需對分片進行操作。
ES 自動在所有節點中分布所有分片,當節點故障時,會把分片移到其他節點,當有新節點添加進來時,也會自動把一些分片移過來。
- Replicas 副本
主分片的拷貝,副本的作用:
1)當主分片故障後,其副本可以提升為主分片。
2)主分片及其副本都可以處理查詢請求,可以提升性能。
- Aliases 別名
用於指定索引或索引集的替代名稱。
當我們想從多個索引中獲取文檔時非常有用。
- Template 模板
用戶對多個索引指定通用的 mapping 和 Setting。
每當創建與模板中定義的特定模式匹配的新索引時,模板將應用於該索引。
創建索引時特別定義的任何 mapping/Setting 都將優先於模板中的定義。
2. API 操作
測試環境搭建
使用的 ES 版本為 7.5.1。
下面使用docker啟動一個單節點環境:
docker run -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" docker.elastic.co/elasticsearch/elasticsearch:7.5.1
測試:
$ curl -X GET "localhost:9200/_cat/nodes?v&pretty" ip heap.percent ram.percent cpu load_1m load_5m load_15m node.role master name 172.17.0.2 7 97 2 0.96 0.61 0.25 dilm * 245e340eba97 $ curl localhost:9200 { "name" : "245e340eba97", "cluster_name" : "docker-cluster", "cluster_uuid" : "mq_bxY5zTjCpmJU0xOLSbA", "version" : { "number" : "7.5.1", "build_flavor" : "default", "build_type" : "docker", "build_hash" : "3ae9ac9a93c95bd0cdc054951cf95d88e1e18d96", "build_date" : "2019-12-16T22:57:37.835892Z", "build_snapshot" : false, "lucene_version" : "8.3.0", "minimum_wire_compatibility_version" : "6.8.0", "minimum_index_compatibility_version" : "6.0.0-beta1" }, "tagline" : "You Know, for Search" }參考文檔:
https://www.elastic.co/guide/en/elasticsearch/reference/7.5/docker.html
實踐操作
- 創建索引
curl -X PUT "localhost:9200/traveler?pretty" -H 'Content-Type: application/json' -d' { "settings":{ "number_of_shards":5, "number_of_replicas":2 }, "mappings":{ "properties":{ "name":{ "type":"keyword" }, "age":{ "type":"integer" }, "background":{ "type":"text" }, "nationality":{ "type":"keyword" } } } } '- 插入文檔
curl -X PUT "localhost:9200/traveler/_doc/1?pretty" -H 'Content-Type: application/json' -d' { "name":"John Doe", "age":"23", "background":"Born and brought up in California. Engineer by profession. Loves to cook", "nationality":"British" } '- 讀取文檔
curl -X GET "localhost:9200/traveler/_doc/1?pretty"
- 刪除文檔
curl -X DELETE "localhost:9200/traveler/_doc/1?pretty"
- 刪除索引
curl -X DELETE "localhost:9200/traveler?pretty"
- 所有索引列表
curl -X GET "localhost:9200/_cat/indices"
- 查看集群健康情況
curl -X GET "localhost:9200/_cat/health?v"
- 查看某個索引的資訊
# mapping + setting curl -X GET "localhost:9200/traveler?pretty" # mapping curl -X GET "localhost:9200/traveler/_mapping?pretty" # setting curl -X GET "localhost:9200/traveler/_settings?pretty"
- 為索引設置別名
curl -X POST "localhost:9200/_aliases" -H 'Content-Type: application/json' -d' { "actions":[ { "add":{ "index":"traveler", "alias":"read_alias" } } ] } '- 獲取索引中的所有文檔
curl -X GET "localhost:9200/traveler/_search?pretty"
結果中的關鍵項: took - 此次查詢耗時,毫秒。 timed_out - 查詢是否超時。 _shards - 查詢了分片的情況,如一共查詢了幾個分片、成功了幾個。 hits - 查詢結果。 hits.total - 結果文檔數。 hits.hits - 結果數組,默認只顯示前10個文檔。 hits.max_score - 匹配度最高的文檔的分值。 hits.hits._score - 此文檔匹配度分值。
- 獲取所有中的文檔總數
curl -X GET "localhost:9200/traveler/_count?pretty"
- 匹配查詢
curl -X GET "localhost:9200/traveler/_search?pretty" -H 'Content-Type: application/json' -d' { "query":{ "match":{ "background":"brought up California Loves cook" } } } '匹配條件是 "background",其值會被處理為數組:[「brought」, 「up」, 「california」, 「loves」, 「cook」]。
只要其中的某一個與文檔中的 "background" 值相匹配,文檔就會被返回。
- term 查詢
curl -X GET "localhost:9200/traveler/_search?pretty" -H 'Content-Type: application/json' -d' { "query":{ "term":{ "name":{ "value":"John Doe" } } } } '這用於獲取在提供的欄位中包含確切術語的文檔。
適用於 keyword, numeric, date, boolean 類型的欄位。
- terms 查詢
curl -X GET "localhost:9200/traveler/_search?pretty" -H 'Content-Type: application/json' -d' { "query":{ "terms":{ "name":[ "John Doe", "Jack Ripper", "Buzz Aldrin" ] } } } '類似 IN 查詢,匹配一個或多個。
- 前綴匹配查詢
curl -X GET "localhost:9200/traveler/_search?pretty" -H 'Content-Type: application/json' -d' { "query":{ "prefix":{ "name":"Joh" } } } '- 正則查詢
curl -X GET "localhost:9200/traveler/_search?pretty" -H 'Content-Type: application/json' -d' { "query":{ "regexp":{ "name":{ "value":"J.*e" } } } } '- 單次多查詢
在一個請求中執行多個查詢操作。
curl -X GET "localhost:9200/_msearch?pretty" -H 'Content-Type: application/x-ndjson' -d' {"index":"traveler"} {"query":{"terms":{"name":["John Doe","Jack Ripper","Barack Obama"]}}} {} {"query":{"prefix":{"name":"Buzz"}}} {"index":"traveler"} {"query":{"match_all":{}}} '