我是啤酒就辣條。但行好事,莫問前程。html
官方爲咱們提供了多種語言操做Elasticsearch的API,能夠很方便的在項目中操做。學習利用原生請求操做Elasticsearch,方便維護數據庫,還能加快學習使用不一樣語言的API。正則表達式
本博客使用kibana發起請求,使用kibana能夠查看快捷鍵。數據庫
建立索引使用PUT
請求,後面跟上索引名稱就行了,因爲7.x默認type爲_doc
,因此後面沒必要跟上type了。在PUT簡單請求同時,能夠加上JSON請求體,進行復雜建立。json
PUT /user { "settings": { "index": { "number_of_shards": 3, "number_of_replicas": 2 } }, "mappings": { "properties": { "name": { "type": "text" }, "age": {"type": "short"}, "city":{"type": "keyword"} } } }
建立索引user
,能夠經過參數setting
設置分片和副本數,經過number_of_shards
設置一共有3個分片,經過number_of_replicas
給每一個分片設置2個副本,默認不指定的話,這兩個參數都是1。經過mappings
規定文檔各個Filed插入類型。此外,還能夠設置aliases
字段,給索引建立別名,這樣不只能夠經過別名訪問該索引,還能夠定義查詢條件、指定查詢分片等等,詳情請參考。數組
刪除索引,使用DELETE請求。瀏覽器
DELETE /user
查看索引,使用GET
請求,能夠查看索引設置的參數。緩存
刪除以後,我又從新添加索引,沒有設置settings,因此分片和副本都是1。app
你也能夠經過在索引後面加參數來查看某一具體參數,如:elasticsearch
GET /user/_settings GET /user/_mappings GET /user/_aliases
能夠經過PUT
請求修改部分索引的settings,例如,分片副本數量能夠修改,可是分片數量不能夠經過這種方式修改。ide
PUT /user/_settings { "number_of_replicas": 3 }
能夠經過以上請求,修改分片副本。
建立好索引,來看下文檔的增刪改查,這是平常業務用的最多的地方。
新增文檔使用PUT
、POST
請求。
PUT /<target>/_doc/<_id> POST /<target>/_doc/ PUT /<target>/_create/<_id> POST /<target>/_create/<_id>
target
爲索引名稱,_doc
爲默認type。經過前兩種請求可看出,id能夠自行指定,也能夠由ES自動生成。_create
能夠保證只有當文檔不存在的時候進行插入,而_doc
還能夠用於文檔更新。
POST /user/_doc/1 { "name":"pjjlt", "age":26, "city":"sjz" }
更新文檔可使用PUT
或者POST
請求關鍵字,全量更新。
POST /user/_doc/1 { "name":"pjjlt", "age":3, "city":"sjz" }
還能夠經過_update
命令局部更新,所謂局部更新,是講請求體內不須要加入所有字段,只加入須要修改的字段就好,其餘字段不變。全量更新會替換整個文檔。
POST /user/_update/1 { "doc":{ "age": 26 } }
此外還能夠經過腳本修改,例如將全部存在age
字段的文檔,其值改爲5歲。
POST /user/_update_by_query { "script": { "source": "ctx._source['age']=5" }, "query": { "bool": { "must": [ { "exists": { "field": "age" } } ] } } }
此外update
和_update_by_query
字段還能夠修改Filed
,例如將name修改爲name1,這塊內容使用較少,如感興趣,請參考官方文檔。
刪除文檔可使用DELEETE
請求,刪除指定id的文檔,也可使用_delete_by_query
,刪除指定條件下的文檔。
DELETE /user/_doc/1
POST /user/_delete_by_query { "query": { "match": { "name": "pjjlt" } } }
查找文檔是ES操做最精彩的部分,這裏只介紹簡單的查詢,複雜查詢、聚合查詢後面會介紹。
根據id查詢某文檔。
GET /user/_doc/1
查找某索引下的所有文檔
GET /user/_search?pretty
pretty
參數在瀏覽器中才會發揮做用,格式化返回json的。以上這條命令默認返回10條數據,想返回更多數據能夠添加size
字段。
GET /user/_search?pretty&size=20
能夠看出,數據部分在hits
裏面,Spring提供的elasticsearch客戶端會有對應的實體類,在項目中很方便的使用。下面看下這幾部分的含義。
元素 | 含義 |
---|---|
took | 運行查詢須要多長時間 |
time_out | 請求是否超時 |
_shards | 搜索了多少分片,多少成功 多少跳過,多少失敗 |
hits.total | 總共有多少數據 |
hits._max_score | 查詢到的文檔中,關聯度最大文檔分數 |
hits.hits._source | 查詢到的數據 |
hits.hits.id | 某文檔的主鍵 |
批量操做是指,一批命令同時執行(減小IO),這些命令不必定是同種類型。
使用_bulk
命令能夠進行文檔的批量增刪改。
POST _bulk { "update" : { "_index" : "user", "_id" : "1" } } { "doc" : {"age" : 18} } { "create" : { "_index" : "user", "_id" : "2" } } { "name" : "小明","age":32,"city":"beijing" } { "create" : { "_index" : "user", "_id" : "3" } } { "name" : "小紅","age":21,"city":"sjz" } { "create" : { "_index" : "user", "_id" : "4" } } { "name" : "mark","age":22,"city":"tianjin" } { "delete" : { "_index" : "user", "_id" : "4" } }
以上命令更新了id爲1文檔的年齡,新增id爲二、三、4的文檔,再刪除id爲4的文檔。
上邊的命令堆在一塊兒不方便看,下面單獨寫看,方便讀者查看。
POST _bulk { "create" : { "_index" : "user", "_id" : "2" } } { "name" : "小明","age":32,"city":"beijing" } { "create" : { "_index" : "user", "_id" : "3" } } { "name" : "小紅","age":21,"city":"sjz" } { "index" : { "_index" : "user", "_id" : "4" } } { "name" : "mark","age":22,"city":"tianjin" }
create
命令是隻有文檔不存在,纔會插入,index
會判斷若是存在就更新,不存在就插入。
POST _bulk { "update" : { "_index" : "user", "_id" : "1" } } { "doc" : {"age" : 18} } { "update" : { "_index" : "user", "_id" : "2" } } { "doc" : {"age" : 20} }
和新增同樣,update
命令下一行須要緊跟這data數據。
POST _bulk { "delete" : { "_index" : "user", "_id" : "3" } } { "delete" : { "_index" : "user", "_id" : "4" } }
批量查找,使用_mget
關鍵字,批量查找若是不跨越索引,也具備簡寫形式。
GET /_mget { "docs": [ { "_index": "user", "_id": "1" }, { "_index": "user", "_id": "2" } ] } # 還能夠簡寫形式 POST /user/_mget { "ids": [ "1", "2", "3" ] }
Elasticsearch提供了一個完整的基於JSON的查詢DSL(領域特定語言)來定義查詢。能夠將查詢DSL看做查詢的AST(抽象語法樹),它由兩種類型的子句組成: Leaf query clauses(葉查詢子句)和 Compound query clauses(複合查詢子句)
以上摘自官網,簡單來講,DSL就是將查詢條件放到JSON中,進行查詢。
Leaf query clauses在特定字段上查找特定的值,例如match
、term
、range
查詢等等。
Compound query clauses將葉查詢子句和其餘符合查詢子句結合起來,例如bool
查詢等等。
match是一個標準查詢,當查詢一個文本的時候,會先將文本分詞。當查詢確切值的時候,會搜索給定的值,例如數字、日期、布爾或者被not_analyzed的字符串。
GET /user/_search { "query": { "match": { "name":"小明" } } }
上面的操做會先將「小明」分詞爲「小」、「明」(固然具體還要看你的分詞器),而後再去全部文檔中查找與之相匹配的文檔,並根據關聯度排序返回。
match_phrase會保留空格,match會把空格忽略。
GET /user/_search { "query": { "match_phrase": { "name":"小 明" } } }
注意,分詞是空格會給前一個元素,好比上面的字符串分子以後是,「小 」,「明」。
多字段查詢,一個查詢條件,看全部多個字段是否有與之匹配的字段。後面咱們也可使用
should
更加靈活。
GET /user/_search { "query": { "multi_match": { "query": "哈哈", "fields": [ "name","city" ] } } }
匹配全部,並可設置這些文檔的_score
,默認_score
爲1,辣條君認爲這裏沒有計算_score
,因此速度會快不少。
GET /user/_search { "query": { "match_all": { "boost" : 1.2 } } }
boost
參數能夠省略,默認是1。
term是一種徹底匹配,主要用於精確查找,例如數字、ID、郵件地址等。
GET /user/_search { "query": { "term": { "age": 18 } } }
terms是term多條件查詢,參數能夠傳遞多個,以數組的形式表示。
GET /user/_search { "query": { "terms": { "age":[18,21] } } }
通配符,看示例容易理解,通配符能夠解決分詞匹配不到的問題,例如'haha' 能夠經過'*a'匹配。
GET /user/_search { "query": { "wildcard": { "name":"*a" } } }
查看某文檔是否有某屬性,返回包含這個
Filed
的文檔。
GET /user/_search { "query": { "exists": { "field": "name" } } }
返回與查詢條件相同或者類似的匹配內容。
GET /user/_search { "query": { "fuzzy": { "name":"mjjlt" } } }
搜索條件是mjjlt
,能夠搜出來name爲pjjlt
的文檔。這個操做是否是在百度的時候常常見到呢?
多id查詢,這個id是主鍵id,即你規定或者自動生成那個。
GET /user/_search { "query": { "ids": { "values":[1,2,3] } } }
前綴匹配
GET /user/_search { "query": { "prefix": { "name":"pj" } } }
範圍匹配。參數能夠是 gt(大於)、 gte(大於等於)、 lt(小於)、 lte(小於等於)
GET /user/_search { "query": { "range": { "age":{ "gt":1, "lt":30 } } } }
正則匹配。value是正則表達式,flags是匹配格式,默認是ALL,開啓全部。更多格式 請戳
GET /user/_search { "query": { "regexp": { "name":{ "value": "p.*t", "flags": "ALL" } } } }
bool 能夠用來組合其餘子查詢。其中常包含的子查詢包含:must、filter、should、must_not
must
內部的條件必須包含,內部條件是and
的關係。如查看全部name中包含「小」而且age是32的用戶文檔。
GET /user/_search { "query": { "bool" : { "must": [ {"term" : { "name" : "小" }}, {"term" : { "age" : 32 }} ] } } }
filter
是文檔經過一些條件過濾下,這是四個關鍵詞中惟一和關聯度無關的,不會計算_score,常用的過濾器會產生緩存。
GET /user/_search { "query": { "bool" : { "filter": { "term" : { "name" : "小" } } } } }
對比兩張圖能夠看出,filter並無計算_score,搜索速度較快。
這個和must
相反,文檔某字段中必定不能包含某個值,至關於「非」。
should
能夠看作or
的關係,例以下面查詢name包含"小"或者年齡是18歲的用戶。
GET /user/_search { "query": { "bool" : { "should": [ {"term" : { "name" : "小" }}, {"term" : { "age" : 18 }} ] } } }
Elasticsearch除全文檢索功能外提供的針對Elasticsearch數據作統計分析的功能。能夠查詢某組數據的最大最小值,分組查詢某些數據。
這裏經常使用的數學操做有min
(最小)、max
(最大)、sum
(和)、avg
(平均數)。注意這些操做只能輸出一個分析結果。使用方式大同小異。
GET /user/_search { "aggs" : { "avg_user_age" : { "avg" : { "field" : "age" } } } }
以上示例查詢全部用戶的平均年齡,返回全部文檔和聚合查詢結果。aggs
是聚合查詢關鍵詞,avg_user_age
是查詢名稱,用戶能夠自行定義。
計算某字段去重後的數量
GET /user/_search { "aggs" : { "avg_user" : { "cardinality" : { "field" : "age" } } } }
能夠計算,全部文檔中年齡不相同的文檔個數。
對指定字段的值按從小到大累計每一個值對應的文檔數的佔比,返回指定佔比比例對應的值。默認統計百分比爲[ 1, 5, 25, 50, 75, 95, 99 ]
GET /user/_search { "aggs" : { "avg_user" : { "percentiles": { "field" : "age" } } } } # 返回值(省略文檔部分,只分析結果部分) "aggregations" : { "avg_user" : { "values" : { "1.0" : 12.0, "5.0" : 12.0, "25.0" : 20.25, "50.0" : 29.0, "75.0" : 57.75, "95.0" : 123.0, "99.0" : 123.0 } } }
能夠看出,前1%的用戶小於12歲,5%的用戶小於12歲,25%的用戶小於20.25歲,50%的用戶小於29歲。。。
percentiles是經過百分比求出文檔某字段,percentile_ranks是給定文檔中的某字段求百分比。
GET /user/_search { "aggs" : { "avg_user" : { "percentile_ranks": { "field" : "age", "values" : [18, 30] } } } } # 返回值(省略文檔部分,只分析結果部分) "aggregations" : { "avg_user" : { "values" : { "18.0" : 18.51851851851852, "30.0" : 54.44444444444445 } } }
能夠看出,小於等於18歲的用戶有18.52%,小於等於30歲的用戶有54.4%。
top_hits能夠獲得某條件下top n的文檔。
GET /user/_search { "aggs": { "avg_user" : { "top_hits": { "sort": [ { "age": { "order": "asc" } } ], "size": 1 } } }, "size": 0 }
取年齡最小的那一個。
相似於分組的概念。
根據給定的filed分組,返回每組多少文檔。
GET /user/_search { "aggs" : { "avg_user" : { "terms": { "field": "city" } } } }
以上根據城市分組,看每一個城市有多少用戶。
根據區間分組
GET /user/_search { "aggs": { "price_ranges": { "range": { "field": "age", "ranges": [ { "to": 20 }, { "from": 20, "to": 30 }, { "from": 30 } ] } } } }
能夠查看每一個年齡層的用戶數量。
還有些頗有趣的指令,例如[IP range]能夠根據ip段區間分組,之後用到再說吧,但願文本能夠不段更新的說...