DevTools
注:ElasticSearch裏面有 index
和 type
的概念:index稱爲索引,type爲文檔類型,一個index下面有多個type,每個type的字段可以不一樣。這類似於關係型數據庫的 database 和 table 的概念。
實際使用中建議一個index
裏面僅有一個type
,名稱可以和index一致,或者使用固定的doc
。
節點操作
查看健康狀態
GET /_cat/health?format=json
format=json
表示輸出json格式,默認是文本格式。
健康狀態有3種:
- Green - 正常(集羣功能齊全)
- Yellow - 所有數據均可用,但尚未分配一些副本(羣集功能齊全)
- Red - 某些數據由於某種原因不可用(羣集部分功能可用)
注意:當羣集爲紅色時,它將繼續提供來自可用分片的搜索請求,但您可能需要儘快修復它,因爲存在未分配的分片。
查看節點
GET /_cat/nodes?format=json
索引
創建index
PUT /customer
注:實際項目裏一般是不會直接這樣創建 index 的,這裏僅爲演示。一般都是通過創建 mapping 手動定義 index 或者自動生成 index 。
刪除index
DELETE /customer
注:刪除索引會把數據一併刪除。實際操作請謹慎。
查看所有index
GET /_cat/indices?format=json
增刪改查
ES文檔有一些缺省字段,稱之爲Meta-Fields
,例如_index
、_type
、_id
等,查詢文檔的時候會返回。
按ID新增數據
type爲doc:
PUT /customer/_doc/1
{
"name": "John Doe"
}
PUT /customer/_doc/2
{
"name": "yujc",
"age":22
}
如果索引index不存在,直接新增數據也會同時創建index。
按ID更新數據
PUT /customer/_doc/2
{
"name": "yujc2"
}
POST /customer/_doc/1
{
"name": "yujc2",
"age":22
}
name
字段會被修改,而且_version
會被修改爲2。該操作實際是覆蓋數據。
按ID查詢數據
GET /customer/_doc/1
直接新增數據
我們也可以不指定文檔ID從而直接新增數據:
POST /customer/_doc
{
"name": "yujc",
"age":23
}
注意這裏使用的動作是
POST
。PUT
新增數據必須指定文檔ID。
更新部分字段
如果只是想更新指定字段,必須使用POST
加參數的形式:
POST /customer/_doc/1/_update
{
"doc":{"name": "John"}
}
其中_update
表示更新。Json裏doc
必須有,否則會報錯。
增加字段
在已有的數據基礎上增加一個year
字段,不會覆蓋已有數據
POST /customer/_doc/1/_update
{
"doc":{"year": 2018}
}
也可以使用簡單腳本執行更新。此示例使用腳本將年齡增加5:
POST /customer/doc/1/_update
{
"script":"ctx._source.age+=5"
}
按ID刪除數據
DELETE /customer/_doc/1
查詢指定 Index 的 mapping
GET /customer/_mapping
批量操作
批量創建
POST /customer/_doc/_bulk
{"index":{"_id":"3"}}
{"name": "John Doe3" }
{"index":{"_id":"4"}}
{"name": "Jane Doe4" }
該操作會新增2條記錄,其中文檔第1行和第3行提供的是要操作的文檔id,第2行和第4行是相應的源文檔,即數據內容。這裏對文檔的操作是index
,也可以是create
,二者都是創建文檔,只是如果文檔已存在,index
會覆蓋,create
會失敗。
批量更新、刪除
POST /customer/_doc/_bulk
{"update":{"_id":"1"}}
{"doc": { "name": "John Doe becomes Jane Doe" } }
{"delete":{"_id":"2"}}
該操作會更新ID爲1的文檔,刪除ID爲2的文檔。對於刪除操作,之後沒有相應的源文檔,因爲刪除只需要刪除文檔的ID。
注意:批量操作如果某條失敗了,並不影響下一條繼續執行。
按條件更新
curl -X POST
http://127.0.0.1:9200/test/_doc/_update_by_query
-H "Content-Type: application/json"
-d '{"script":{"source":"ctx._source[\"is_pub\"]=1"},"query":{"match_all":{}}}'
這個示例的含義是將文檔test/_doc
的所有文檔的is_pub
字段設置爲1。
按條件刪除
curl -X POST
http://127.0.0.1:9200/test/doc/_delete_by_query
-H "Content-Type: application/json"
-d '{"query":{"bool":{"filter":{"range":{"id":{"gt":1661208}}}}}}'
這個示例的含義是將文檔test/doc
裏字段 id 符合id>1661208
的全部刪除。
全文檢索
返回字段含義
- took – Elasticsearch執行搜索的時間(以毫秒爲單位)
- timed_out – 搜索是否超時
- _shards – 搜索了多少個分片,以及搜索成功/失敗分片的計數
- hits – 搜索結果,是個對象
- hits.total – 符合我們搜索條件的文檔總數
- hits.hits – 實際的搜索結果數組(默認爲前10個文檔)
- hits.sort - 對結果進行排序(如果按score排序則沒有該字段)
- hits._score、max_score -分數
- _index:索引庫
- _type:文檔類型
- _id:文檔id
- _source:文檔的源數據
match查詢
GET /bank/_search
{
"query" : {
"match" : { "address" : "Avenue" }
}
}
curl:
curl -XGET -H "Content-Type: application/json" "localhost:9200/bank/_search?pretty" -d '{"query":{"match":{"address":"Avenue"}}}'
上述查詢返回結果是address
含有Avenue
的結果。
term查詢
GET /bank/_search
{
"query" : {
"term" : { "address" : "Avenue" }
}
}
curl:
curl -XGET
-H "Content-Type: application/json" "localhost:9200/bank/_search?pretty"
-d '{"query":{"term":{"address":"Avenue"}}}'
上述查詢返回結果是address
等於Avenue
的結果。
分頁(from/size)
分頁使用關鍵字from、size,分別表示偏移量、分頁大小。
GET /bank/_search
{
"query": { "match_all": {} },
"from": 0,
"size": 2
}
from默認是0,size默認是10。
注意:ES的from、size分頁不是真正的分頁,稱之爲淺分頁。from+ size不能超過
index.max_result_window
默認爲10,000
的索引設置。
排序(sort)
字段排序關鍵字是sort。支持升序(asc)、降序(desc)。默認是對_score
字段進行排序。
GET /bank/_search
{
"query": { "match_all": {} },
"sort": [
{ "account_number": "asc" }
],
"from":0,
"size":10
}
腳本排序
允許基於自定義腳本進行排序,這是一個示例:
GET bank/account/_search
{
"query": { "range": { "age": {"gt": 20} }},
"sort" : {
"_script" : {
"type" : "number",
"script" : {
"lang": "painless",
"source": "doc['account_number'].value * params.factor",
"params" : {
"factor" : 1.1
}
},
"order" : "asc"
}
}
}
上述查詢是使用腳本進行排序:按``account_number * 1.1的結果進行升序。其中
lang指的是使用的腳本語言類型爲
painless。
painless支持
Math.log`函數。
過濾字段
默認情況下,ES返回所有字段。這被稱爲源(_source
搜索命中中的字段)。如果我們不希望返回所有字段,我們可以只請求返回源中的幾個字段。
GET /bank/_search
{
"query": { "match_all": {} },
"_source": ["account_number", "balance"]
}
通過_source
關鍵字可以實現字段過濾。
返回腳本字段
可以通過腳本動態返回新定義字段。示例:
GET bank/account/_search
{
"query" : {
"match_all": {}
},
"size":2,
"script_fields" : {
"age2" : {
"script" : {
"lang": "painless",
"source": "doc['age'].value * 2"
}
},
"age3" : {
"script" : {
"lang": "painless",
"source": "params['_source']['age'] * params.factor",
"params" : {
"factor" : 2.0
}
}
}
}
}
結果:
{
"took": 2,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 1000,
"max_score": 1,
"hits": [
{
"_index": "bank",
"_type": "account",
"_id": "25",
"_score": 1,
"fields": {
"age3": [
78
],
"age2": [
78
]
}
},
{
"_index": "bank",
"_type": "account",
"_id": "44",
"_score": 1,
"fields": {
"age3": [
74
],
"age2": [
74
]
}
}
]
}
}
注意:使用
doc['my_field_name'].value
比使用params['_source']['my_field_name']
更快更效率,推薦使用。
AND查詢
如果我們想同時查詢符合A和B字段的結果,該怎麼查呢?可以使用must關鍵字組合。
GET /bank/_search
{
"query": {
"bool": {
"must": [
{ "match": { "address": "mill" } },
{ "match": { "address": "lane" } }
]
}
}
}
GET /bank/_search
{
"query": {
"bool": {
"must": [
{ "match": { "account_number":136 } },
{ "match": { "address": "lane" } },
{ "match": { "city": "Urie" } }
]
}
}
}
OR查詢
ES使用should關鍵字來實現OR查詢。
GET /bank/_search
{
"query": {
"bool": {
"should": [
{ "match": { "account_number":136 } },
{ "match": { "address": "lane" } },
{ "match": { "city": "Urie" } }
]
}
}
}
AND取反查
must_not
關鍵字實現了既不包含A也不包含B的查詢。
GET /bank/_search
{
"query": {
"bool": {
"must_not": [
{ "match": { "address": "mill" } },
{ "match": { "address": "lane" } }
]
}
}
表示 address 字段需要符合既不包含 mill 也不包含 lane。
布爾組合查詢
我們可以組合 must 、should 、must_not 進行復雜的查詢。
- A AND NOT B
GET /bank/_search
{
"query": {
"bool": {
"must": [
{ "match": { "age": 40 } }
],
"must_not": [
{ "match": { "state": "ID" } }
]
}
}
}
相當於SQL:
select * from bank where age=40 and state!= "ID";
- A AND (B OR C)
GET /bank/_search
{
"query":{
"bool":{
"must":[
{"match":{"age":39}},
{"bool":
{"should":[
{"match":{"city":"Nicholson"}},
{"match":{"city":"Yardville"}}
]}
}
]
}
}
}
相當於SQL:
select * from bank where age=39 and (city="Nicholson" or city="Yardville");
範圍查詢
GET /bank/_search
{
"query": {
"bool": {
"must": { "match_all": {} },
"filter": {
"range": {
"balance": {
"gte": 20000,
"lte": 30000
}
}
}
}
}
}
相當於SQL:
select * from bank where balance between 20000 and 30000;
多字段範圍查詢:
GET /bank/_search
{
"query": {
"bool": {
"must": { "match_all": {} },
"filter": {
"bool":{
"must":[
{"range": {"balance": {"gte": 20000,"lte": 30000}}},
{"range": {"age": {"gte": 30}}}
]
}
}
}
}
}
相當於SQL:
select * from bank where (balance between 20000 and 30000) and (age > 30);
聚合查詢
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
多重聚合
我們可以在聚合的基礎上再進行聚合,例如求和、求平均值等等。
GET /bank/_search
{
"size": 0,
"aggs": {
"group_by_state": {
"terms": {
"field": "state.keyword"
},
"aggs": {
"average_balance": {
"avg": {
"field": "balance"
}
}
}
}
}
}
Mapping
Mapping類似於數據庫中的表結構定義,主要作用如下:
- 定義Index下字段名(Field Name)
- 定義字段的類型,比如數值型,字符串型、布爾型等
- 定義倒排索引的相關配置,比如是否索引、記錄postion等
Mapping完整的內容可以分爲四部分內容:
- 字段類型(Field datatypes)
- 元字段(Meta-Fields)
- Mapping參數配置(Mapping parameters)
- 動態Mapping(Dynamic Mapping)