本文非徹底直譯譯文,主要參考的的是 elasticsearch 6.5 版的官網文檔 Getting Started,能夠把這篇文章理解爲我的學習筆記,我力求詳略得當吧。node
文末會附上 Getting Started 閱讀梳理的思惟導圖。linux
爲了能更加輕鬆地進入 elasticsearch 的世界,本文將先從基礎角度給介紹了 es 的使用。git
Elasticsearch 是一款開源的全文搜索與分析引擎,它擁有高擴展、大容量數據的存儲和處理特性,有着近乎實時的處理效果。elasticsearch 的使用場景仍是比較多的,好比 APP 的搜索服務、ELK 實現日誌收集與分析、BI 商業智能等。github
本文會逐步引導你們進入 elasticsearch 的世界,初步窺探它的使用。相關內容涉及以下:sql
總體上的內容仍是比較多的。數據庫
Elasticsearch 中有一些基礎但很核心的概念須要咱們提早了解,它們對咱們的學習將起到很大幫助。json
具體是哪些概念呢?windows
下面咱們將逐一介紹。bash
什麼是近實時?
它表示一個文檔從被索引(存儲使文檔可搜索)到真正能被搜索之間有一個短暫的延遲,而非實時,這個延遲默認是 1 秒。固然,默認延遲能夠修改的。
集羣是節點的集合。
集羣實現了在多節點上進行大容量數據存儲和搜索的能力。每一個集羣都擁有惟一名稱,而節點正是根據集羣的名稱決定是否加入某個集羣。不一樣環境的集羣的名稱不能相同,如開發、測試、線上三套環境,集羣可分別命名爲 logging-dev、logging-test、logging-prod。
節點,集羣組成的一部分,負責具體的事務處理,好比數據存儲、文檔索引、搜索執行等。節點也有惟一個名稱,若是沒有指定將隨機生成。
節點可經過配置集羣名稱,指定加入哪一個集羣,節點默認的集羣名稱是 elasticsearch。若是咱們在一個網絡環境下啓動多個節點,而且它們之間能夠相互發現,就將會自動組織一個名稱爲 elasticsearch 的集羣。
索引是一系列類似文檔的集合,例如,咱們把客戶信息存放到一個索引,訂單信息存儲到另外一個索引中。索引可經過名稱識別,名稱必須小寫。當操做文檔時,咱們須要經過索引名稱指定。
索引的數量,集羣中並無限制定義索引的數量。
elasticsearch 6.0 已丟棄功能,不具體介紹了。
有一點須要注意,爲與老版本兼容,該功能暫未完全移除,當前一個索引仍可設置類型,但當前只能指定一個類型。通常狀況下,咱們設置一個固定 type 便可,好比 _doc。
被索引的基礎信息單元,好比一個客戶、一件產品、或是一筆訂單。文檔可用 JSON 形式表示,它是一種很是廣泛的數據交換格式。索引中,咱們能夠存聽任意數量的文檔。
分片和副本是 elasticsearch 很是核心的概念。
咱們知道,elasticsearch 存儲的數據量能突破單個硬件的限制,數據處理速度有着近實時的水平。這些都和分片和副本有着很大關係。
分片實現了索引文檔分散分佈,而且每一個切片都是功能完善的,索引是獨立的,可能分佈在集羣中的任意節點。分片的重要性主要體如今使 elasticsearch 存儲容量的水平擴展和分佈式並行處理都成爲了現實。
副本提升了 elasticsearch 的容錯能力。網絡環境下,異常隨時可能發生,好比一些節點或分片從網絡中消失。一旦設置了副本,索引就會同時擁有主分片和副本分片。一旦某個分片發生異常,還有其餘分片可替代。並且,副本也能夠提升請求的處理速度,一個分片上的副本可同時並行處理多個請求。
一句話簡述,每一個索引能夠由多個分片組成,而每一個分片也能夠擁有多個副本。
介紹完了核心概念,是否已經開始蠢蠢欲動了?開始安裝本身的集羣吧。
本節主要介紹 elasticsearch 的安裝。另外,因爲要使用 kibana 的 devtools 控制檯,將也會介紹下 kibana 的安裝。
首先安裝依賴,elasticsearch 是 Java 開發,6.5 版依賴 Java 8,建議安裝 Oracle JDK 1.8.0_131。Java 安裝完成後,就能夠開始安裝 elasticsearch 了。
簡單起見,咱們只介紹二進制包的安裝。
安裝過程僅僅三步搞定!
$ curl -L -O https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.5.4.tar.gz
$ tar -xvf elasticsearch-6.5.4.tar.gz
$ cd elasticsearch-6.5.4/bin
$ ./elasticsearch -d # -d 表示後臺啓動
複製代碼
安裝啓動完成後,可經過訪問 localhost:9200 確認下實例運行是否正常。
若是想了解 Mac 的 homebrew 安裝或 windows 下的 MSI Installer Package 安裝,可自行閱讀官方文檔。
Kibana 的安裝與 elasticsearch 的不一樣,須要區別不一樣的平臺系統。本節將介紹 Mac 與 Linux 下的安裝,它們均可以經過下載對應系統的 tar 包完成。
Linux 系統,咱們以 Linux x86_64 爲例。安裝命令以下:
$ wget https://artifacts.elastic.co/downloads/kibana/kibana-6.5.4-linux-x86_64.tar.gz
$ shasum -a 512 kibana-6.5.4-linux-x86_64.tar.gz
$ tar -xzf kibana-6.5.4-linux-x86_64.tar.gz
$ cd kibana-6.5.4-linux-x86_64/
$ ./bin/kibana
複製代碼
MacOS 系統,安裝命令以下:
$ curl -O https://artifacts.elastic.co/downloads/kibana/kibana-6.5.4-darwin-x86_64.tar.gz
$ shasum -a 512 kibana-6.5.4-darwin-x86_64.tar.gz
$ tar -xzf kibana-6.5.4-darwin-x86_64.tar.gz
$ cd kibana-6.5.4-darwin-x86_64/
$ ./bin/kibana
複製代碼
若是但願 kibana 在後臺運行,能夠經過 nohup 實現。完成後,訪問 localhost:5601 下確認狀態,它會默認鏈接本地啓動的 elasticsearch 集羣。
好吧!我仍是不想介紹 Windows 下的安裝。
若是但願啓動一個多節點集羣,咱們能夠修改下啓動命令,在本地同時啓動兩個節點,集羣名稱相同狀況下,它們將會自動組織成一個新的集羣。命令以下:
$ ./bin/elasticsearch -Ecluster.name=cluster_dev -Epath.data=cluster_node01 -Enode.name=node01 -Ehttp.port=9200 -d
$ ./bin/elasticsearch -Ecluster.name=cluster_dev -Epath.data=cluster_node02 -Enode.name=node02 -Ehttp.port=9201 -d
複製代碼
啓動成功後,能夠進入 kibana 的 devtool 執行 _cat/nodes?v,輸出以下:
ip heap.percent ram.percent cpu load_1m load_5m load_15m node.role master name
127.0.0.1 29 75 6 3.31 mdi - node01
127.0.0.1 33 75 6 3.31 mdi * node02
複製代碼
咱們將會看到集羣中已經有了兩個節點。
經歷了前面幾步,elasticsearch 集羣已經安裝完成,但咱們要如何與它交流呢?其實,elasticsearch 已經提供了一套全面且功能強大的 REST API,用於與集羣交互。REST API 涉及功能包括:
本節咱們將簡單介紹上面提到的部分 API。
健康檢查可讓咱們瞭解集羣當前狀態,可經過 _cat API 實現。
示例以下:
GET /_cat/health?v
複製代碼
輸出結果:
epoch timestamp cluster status node.total node.data shards pri relo init unassign pending_tasks max_task_wait_time active_shards_percent
1565884060 23:47:40 cluster_dev green 2 2 22 21 0 0 0 0 - 100.0%
複製代碼
輸出結果顯示,集羣名稱爲 cluster_dev,狀態是 green,當前集羣有 2 個節點。
先重點講講 green 究竟表明什麼意思?
首先,green 表示的是集羣的狀態,對應字段名稱是 status,共有三種狀態,分別是 green、yellow 和 red。
當集羣狀態是 red 時,仍然能夠接收處理搜索請求,但咱們須要馬上修復它。
經過 _cat/nodes,能夠列出當前集羣下的全部節點,前面在啓動一個多節點集羣時,咱們已通過了使用該 API,很少介紹了。
_cat/indices?v 能列出集羣中的全部索引。說明一下,indices 是 index 的複數形式。
GET _cat/indices
複製代碼
輸出以下:
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size
green open us_tweet WXkAeMEvR0eukVOFOM1q3w 5 0 6 0 15.7kb 15.7kb
green open gb_user pbOu0n0XQ96mouQ642eutQ 5 0 1 0 5.7kb 5.7kb
green open us_user idxuhX0LQlekzfbjd6kB5w 5 0 1 0 5.7kb 5.7kb
green open gb_tweet SJTleUerT5CaO9Sl-JwIQg 5 0 6 0 15.7kb 15.7kb
複製代碼
個人本地集羣常常拿來測試,因此這裏會看到已經有不少 index,對於你剛搭建好的集羣,輸出確定就是空的。
接下來,咱們學習下如何建立索引,直接看示例吧。嘗試建立一個名爲 "customer" 的索引,以下:
PUT customer?pretty
複製代碼
PUT 加上索引名稱便可。 customer 索引成功建立後,查看下集羣當前索引列表,以下:
GET _cat/indices
複製代碼
輸出結果以下:
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size
...
green open customer 71RYoldbQ6uXMo56t4bSog 5 1 0 0 1.1kb 460b
...
複製代碼
customer 成功建立,包含 5 個主分片和 1 個副本分片,索引中當前的文檔數量爲 0,索引狀態爲 green。
索引的狀態和集羣同樣,也是 green、yellow 和 red 這 3 個值,而且含義與集羣狀態相似。green 是全功能正常,yellow 表示副本未徹底分配,red 表示部分主分片不可用。咱們能夠測試一下,中止集羣中的一個節點,這時 customer 的狀態將會立刻切換爲 yellow 狀態。
在 elasticsearch 中,"索引" 這個名詞經常會搞暈咱們。通常講到索引,主要是指它的名詞含義,好比咱們說,建立一個 customer 索引。但有時,它又是動詞,好比咱們在增長和更新文檔時,常會說索引一個文檔,在這種狀況下,能夠把它理解爲存儲文檔並使其可搜索。
那如何索引一個文檔呢?好比,索引一個 ID 爲 1 的 customer 文檔到 customer 索引中,以下。
PUT /customer/_doc/1?pretty
{
"name": "John Doe"
}
複製代碼
響應返回:
{
"_index" : "customer",
"_type" : "_doc",
"_id" : "1",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 0,
"_primary_term" : 1
}
複製代碼
結果代表,咱們已經成功建立一個 ID 爲 1 的文檔。從這裏也能看出,在索引一個文檔以前,並不要求咱們明確建立索引 customer,若是 customer 索引不存在,elasticsearch 將會自動幫助咱們建立索引。
檢索剛纔索引的文檔。
GET /customer/_doc/1?pretty
複製代碼
響應以下:
{
"_index" : "customer",
"_type" : "_doc",
"_id" : "1",
"_version" : 1,
"found" : true,
"_source" : { "name": "John Doe" }
}
複製代碼
found 字段代表,咱們已經成功檢索到了一個 ID 爲 1 的文檔。_source 中的內容是檢索文檔的完整內容。
讓咱們刪除掉剛剛建立的索引。
DELETE /customer?pretty
複製代碼
如此,咱們就成功刪除了以前建立的 customer。若是不肯定,可使用 GET _cat/indices 檢查下。
回顧下前面介紹的那些 API,咱們從新再走一遍。
PUT /customer
PUT /customer/_doc/1
{
"name": "John Doe"
}
GET /customer/_doc/1
DELETE /customer
複製代碼
仔細觀察上面的命令,你可能會發現一個比較通用的模式,以下:
<HTTP Verb> /<Index>/<Type>/<ID>
複製代碼
這個模式在 elasticsearch 中很是廣泛,記住它,這將對 elasticsearch 學習之旅將會很是有幫助。
區別於傳統關係型數據庫的實時性特色,elasticsearch 是近實時的,也就是說,在文檔被 create/update/delete 與搜索結果中出現之間將會有 1 秒的延遲。
建立和替換文檔本質上都屬於索引文檔,於是,咱們以前用來建立文檔的命令一樣適用於文檔替換。
由於 customer 索引重建過,咱們從新建立一個 ID 爲 1 的文檔。以下:
PUT /customer/_doc/1?pretty
{
"name": "John Doe"
}
複製代碼
一樣的命令便可實現文檔更新,咱們只須要傳遞不一樣的文檔內容便可,以下:
PUT /customer/_doc/1?pretty
{
"name": "Jane Doe"
}
複製代碼
將 ID 爲 1 的文檔中 name 由 Johh Doe 更新爲 Jane Doe。若是指定 ID 文檔不存在,將會建立新的文檔,不然更新當前文檔。
好比,ID 爲 2 的文檔不存在,經過以下命令建立。
PUT /customer/_doc/2?pretty
{
"name": "Jane Doe"
}
複製代碼
索引文檔時,ID 不是必須的,若是不指定,elasticsearch 會自動爲這個文檔指定一個隨機的 ID,並做爲響應的一部分返回給你。
示例以下:
POST /customer/_doc?pretty
{
"name": "Jane Doe"
}
複製代碼
這種狀況下,咱們須要使用 POST 代替 PUT 提交請求。
響應結果:
{
"_index": "customer",
"_type": "_doc",
"_id": "Z-RnpGwBe6KTDC6t3MGV",
"_version": 1,
"result": "created",
"_shards": {
"total": 1,
"successful": 1,
"failed": 0
},
"_seq_no": 0,
"_primary_term": 1
}
複製代碼
上面能夠看到 elasticsearch 爲咱們生成的文檔 ID,Z-RnpGwBe6KTDC6t3MGV。
說完文檔的索引和替換,咱們再來談談文檔的更新。提早說明,elasticsearch 並不是真的去更新文檔,它的更新操做與替換相似,包含刪除舊文檔和索引新文檔兩個操做。
示例演示,更新前面建立的 ID 爲 1 的文檔,更新 name 字段爲 Jane Doe。
POST /customer/_doc/1/_update?pretty
{
"doc": { "name": "Jane Doe" }
}
複製代碼
示例 2,更新 name 爲 Jane Doe 的同時,增長一個字段 age。
POST /customer/_doc/1/_update?pretty
{
"doc": { "name": "Jane Doe", "age": 20 }
}
複製代碼
示例 3,使用腳本更新文檔,好比將 ID 爲 1 的文檔的字段 age 加 5。
POST /customer/_doc/1/_update?pretty
{
"script": "ctx._source.age += 5"
}
複製代碼
上面的例子,ctx._source 表示的是咱們將要更新的文檔。這裏是經過指定 ID 的方式查詢要更新的文檔,elasticsearch 也能夠像 SQL 同樣,經過複雜查詢實現更新。
刪除文檔最簡單直接,HTTP 方法換成 DELETE,指定文檔 ID 便可。以下:
DELETE /customer/_doc/2?pretty
複製代碼
和更新相似,刪除也能夠根據查詢結果執行刪除,API 是 _delete_by_query。若是是刪除索引中的全部文檔,直接刪除索引更直接點。
通過前面的學習,咱們已經瞭解了 elasticsearch 一些基礎 API 的使用,如文檔的索引、更新、刪除。這一小節介紹一個新的 API,_bulk API,它支持將多個操做打包成一個請求,實現批處理。這樣能夠更加高效的執行操做,也能減小網絡傳遞次數。
一個快速入門案例,以下:
POST /customer/_doc/_bulk?pretty
{"index":{"_id":"1"}}
{"name": "John Doe" }
{"index":{"_id":"2"}}
{"name": "Jane Doe" }
複製代碼
索引了 2 個文檔,一個文檔 ID 1,name 爲 John Doe,另外一個文檔 ID 2,name 爲 Jane Doe。
再看一個案例,以下:
POST /customer/_doc/_bulk?pretty
{"update":{"_id":"1"}}
{"doc": { "name": "John Doe becomes Jane Doe" } }
{"delete":{"_id":"2"}}
複製代碼
批處理包含 2 個操做,更新 ID 爲 1 文檔的 name 字段和刪除 ID 爲 2 的文檔。
批處理中的一個操做失敗並不會致使整個 bulk API 處理失敗,若是一個操做失敗,剩下來的其餘操做仍會繼續執行。bulk API 處理完成後,響應結果中會包含每一個操做的處理結果。
本節內容主要涉及兩個方面:搜索與分析。
搜索分析不可缺乏數據,咱們將使用 elastic 官方提供的數據樣本,相對而言,應該比本身的生成更符合真實場景。
一個文檔,示例以下:
{
"account_number": 0,
"balance": 16623,
"firstname": "Bradshaw",
"lastname": "Mckenzie",
"age": 29,
"gender": "F",
"address": "244 Columbus Place",
"employer": "Euron",
"email": "bradshawmckenzie@euron.com",
"city": "Hobucken",
"state": "CO"
}
複製代碼
官方的數據是用工具隨機生成的,工具地址。有興趣,能夠設置本身的數據生成規則。
開始數據加載以前,要先下載數據,下載地址。
$ wget https://raw.githubusercontent.com/elastic/elasticsearch/master/docs/src/test/resources/accounts.json
複製代碼
下載完成後,執行以下命令加載數據:
$ curl -H "Content-Type: application/json" -XPOST "localhost:9200/bank/_doc/_bulk?pretty&refresh" --data-binary "@accounts.json"
複製代碼
查看索引信息
$ curl "localhost:9200/_cat/indices?v"
複製代碼
響應以下:
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size
green open bank FFcSux-ETmmUlMJNBCEyqA 5 1 1000 0 957kb 482.3kb
複製代碼
能夠看出,咱們已經爲 bank 成功索引了 1000 個文檔。
開始嘗試一些簡單的搜索。有兩種基本的搜索方式:
相對而言,Request Body 方式更靈活,包含了所有的搜索支持。而 URI Search 主要在測試時使用,比較方便。
搜索請求經過 _search 執行。一個示例,經過搜索返回 bank 索引中的全部文檔。
GET /bank/_search?q=*&sort=account_number:asc&pretty
複製代碼
URI Search 方式實現搜索,經過 q=* 執行匹配所有文檔,sort=account_number:asc 指定排序方式。
響應以下:
{
"took" : 63,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 1000,
"max_score" : null,
"hits" : [ {
"_index" : "bank",
"_type" : "_doc",
"_id" : "0",
"sort": [0],
"_score" : null,
"_source" : {"account_number":0,"balance":16623,"firstname":"Bradshaw","lastname":"Mckenzie","age":29,"gender":"F","address":"244 Columbus Place","employer":"Euron","email":"bradshawmckenzie@euron.com","city":"Hobucken","state":"CO"}
}, ...
]
}
}
複製代碼
結果中的各個參數函數以下:
經過 Reuqest Body 方式執行與上面相同的操做,以下:
GET /bank/_search
{
"query": { "match_all": {} },
"sort": [
{ "account_number": "asc" }
]
}
複製代碼
咱們下面主要介紹 Request Body 的使用,畢竟它更增強大。
DSL,全稱 Domain Special Language, 即特定領域語言,elasticsearch 制定了一套 JSON 風格的 DSL 語言。它支持的功能很是全面,剛學習它時,會讓咱們產生一種恐懼,由於它真的很難。咱們能夠先從一些簡單的例子看起。
查詢全部文檔,以下:
GET /bank/_search
{
"query": { "match_all": {} }
}
複製代碼
解剖下請求體。query 定義查詢語句,match_all 就是咱們將會執行的查詢語句,表示匹配索引中的全部文檔。
執行上面的查詢語句默認只會返回 10 條文檔,咱們能夠經過指定 size 參數改變默認獲取文檔數量。以下:
GET /bank/_search
{
"query": { "match_all": {} },
"size": 1
}
複製代碼
經過 from 和 size 能夠實現分頁效果,以下:
GET /bank/_search
{
"query": { "match_all": {} },
"from": 10,
"size": 10
}
複製代碼
from 用於指定文檔偏移的開始位置,至關於 SQL 中的 offset。
文檔默認根據搜索相關度得分排序,不過咱們這裏是默認匹配所有,因此文檔的相關度得分都是1。除了相關度排序,還能夠按其餘字段,好比 balance 字段。以下:
GET /bank/_search
{
"query": { "match_all": {} },
"sort": { "balance": { "order": "desc" } }
}
複製代碼
繼續看下搜索返回文檔字段,默認狀況下,搜索將會返回文檔的全部字段內容。咱們可經過 _source 指定只返回部份內容。
GET /bank/_search
{
"query": { "match_all": {} },
"_source": ["account_number", "balance"]
}
複製代碼
如此,搜索將只返回 account_number
和 balance
兩個字段。 瞭解的 SQL 的朋友能夠將其與 SELECT 指定列類比。
繼續看查詢部分吧!
前面,經過 match_all 查詢匹配了所有文檔。如今,咱們再引入一個新的查詢語句,match,它是基於一個字段的查詢。
查詢 account_number 爲 20 的文檔。示例以下:
GET /bank/_search
{
"query": { "match": { "account_number": 20 } }
}
複製代碼
查詢 address 包含 mill 的文檔。示例以下:
GET /bank/_search
{
"query": { "match": { "address": "mill" } }
}
複製代碼
查詢 address 包含 mill 或 lane 的文檔。示例以下:
GET /bank/_search
{
"query": { "match": { "address": "mill lane" } }
}
複製代碼
match 基於分詞查詢,2 個查詢單詞是 or 的關係。若是咱們就要搜索 "mill lane" 呢? 這時可使用 match_pharse。示例以下:
查詢 address 包含 "mill lane" 的文檔。示例以下:
GET /bank/_search
{
"query": { "match_phrase": { "address": "mill lane" } }
}
複製代碼
繼續介紹 bool 查詢,它容許咱們將上面這些基礎查詢組合造成一個複合查詢。好比,查詢同時包含 "mill" 和 "jane" 的文檔。
示例以下:
GET /bank/_search
{
"query": {
"bool": {
"must": [
{ "match": { "address": "mill" } },
{ "match": { "address": "lane" } }
]
}
}
}
複製代碼
例子中的 bool must 表示文檔必須同時知足兩個 must 條件。若是是隻要知足一個條件便可,咱們可使用 bool should,示例以下:
GET /bank/_search
{
"query": {
"bool": {
"should": [
{ "match": { "address": "mill" } },
{ "match": { "address": "lane" } }
]
}
}
}
複製代碼
若是要求二者必須不知足,咱們可使用 bool must_not,示例以下:
GET /bank/_search
{
"query": {
"bool": {
"must_not": [
{ "match": { "address": "mill" } },
{ "match": { "address": "lane" } }
]
}
}
}
複製代碼
bool 查詢中還能夠將上面的這幾種查詢同時組合起來,同時包含 must、must_not 和 should。
示例以下:
GET /bank/_search
{
"query": {
"bool": {
"must": [
{ "match": { "age": "40" } }
],
"must_not": [
{ "match": { "state": "ID" } }
]
}
}
}
複製代碼
注意一點,若是是 must、must_not 和 should 組合時,should 就缺乏了必須知足一個纔算匹配的限制,這時,咱們能夠經過 minimum_should_match 指定 should 匹配個數。
更復雜的,bool 查詢中還能夠包含其餘的 bool 查詢。這裏先不介紹了。
談到過濾以前,咱們就不得不提文檔相關度評分,相關度評分是用於衡量搜索語句與文檔的匹配程度的一個指標。前面已經提過的查詢語句都會參與到這個指標的計算。
但有時,查詢僅僅是爲了過濾一些不知足條件的文檔,咱們並不但願它們也參與到相關度評分的計算中,由此,咱們並引入了 filter。
前面介紹的 bool 查詢中便支持 filter 功能。它能夠在不影響相關度評分的狀況下,實現文檔過濾。以下:
GET /bank/_search
{
"query": {
"bool": {
"must": { "match_all": {} },
"filter": {
"range": {
"balance": {
"gte": 20000,
"lte": 30000
}
}
}
}
}
}
複製代碼
bool 查詢中包含了 must 和 filter 兩部分。filter 部分經過 range query 實現只查詢 blanace 知足指定區間的文檔,must 中的 match_all 實現所有文檔返回。
除了上面介紹的查詢,如 match_all、match、bool、range,elasticsearch 還有不少其它查詢可用,這裏不詳細介紹了。只要掌握了前面的知識,咱們已經徹底能夠照貓畫虎。
利用 elasticsearch 的聚合能力,咱們能夠實現分組統計,能夠和 SQL 的 GROUP BY 分組和聚合函數類比。搜索和聚合都是經過 _search 請求實現,同一個請求可同時處理搜索與聚合的請求。這樣也能夠幫助咱們節省必要的網絡帶寬。
一個例子,按銀行卡帳號狀態(即 state)分組。默認是返回 top 10。以下:
GET bank/_search
{
"size": 0,
"aggs": {
"group_by_state": {
"terms": {
"field": "state.keyword"
}
}
}
}
複製代碼
如何 SQL 呢?以下:
SELECT state, COUNT(*) FROM bank GROUP BY state ORDER BY COUNT(*) DESC LIMIT 10;
複製代碼
響應以下:
{
"took": 29,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped" : 0,
"failed": 0
},
"hits" : {
"total" : 1000,
"max_score" : 0.0,
"hits" : [ ]
},
"aggregations" : {
"group_by_state" : {
"doc_count_error_upper_bound": 20,
"sum_other_doc_count": 770,
"buckets" : [ {
"key" : "ID",
"doc_count" : 27
}, {
"key" : "TX",
"doc_count" : 27
}, {
"key" : "AL",
"doc_count" : 25
}, {
"key" : "MD",
"doc_count" : 25
}, {
"key" : "TN",
"doc_count" : 23
}, {
"key" : "MA",
"doc_count" : 21
}, {
"key" : "NC",
"doc_count" : 21
}, {
"key" : "ND",
"doc_count" : 21
}, {
"key" : "ME",
"doc_count" : 20
}, {
"key" : "MO",
"doc_count" : 20
} ]
}
}
}
複製代碼
從上面能夠看出,ID 爲 Idaho 的數量爲 27,緊接着是 TX 數量 27,而後是 AL 共 25 個。上面設置 size 爲 0,是爲隱藏搜索結果內容,僅僅顯示聚合結果。
咱們能夠在前面的聚合結果的基礎上,計算 top 10 的帳戶餘額平均值。以下:
GET /bank/_search
{
"size": 0,
"aggs": {
"group_by_state": {
"terms": {
"field": "state.keyword",
"order": {
"average_balance": "desc"
}
},
"aggs": {
"average_balance": {
"avg": {
"field": "balance"
}
}
}
}
}
}
複製代碼
在 group_by_state 中加入子聚合 average_balance,同時在 group_by_state 中,經過 order 配置實現了按 balance 平均值大小排序的需求。
下面這個例子演示瞭如何按年齡區間分組,好比 20-2九、30-39 和 40-49,並在基礎上,繼續按性別分組。最後,計算各個分組 balance 的平均值。
GET /bank/_search
{
"size": 0,
"aggs": {
"group_by_age": {
"range": {
"field": "age",
"ranges": [
{
"from": 20,
"to": 30
},
{
"from": 30,
"to": 40
},
{
"from": 40,
"to": 50
}
]
},
"aggs": {
"group_by_gender": {
"terms": {
"field": "gender.keyword"
},
"aggs": {
"average_balance": {
"avg": {
"field": "balance"
}
}
}
}
}
}
}
}
複製代碼
例子中有兩個分組 group_by_age 和 group_by_gener 以及一個聚合計算 average_balance。
總的來講,上面的例子仍是比較循環漸進的。但主要仍是集中在使用層面,並無太多細節的介紹。若是想了解更多與聚合相關的內容,可自行查詢官方文檔。
Elasticsearch 能夠說是一款即簡單又複雜的產品。本文只是簡單介紹了它的一些基礎,並初步體驗了下它的使用。到此,僅僅算是開啓了一扇門,elasticsearch 的使用遠沒有那麼簡單。
再接再礪吧!朋友!