一、基礎概念
1、Elasticsearch簡介
Lucene是Java語言編寫的全文(全部的文字內容進行分析,建立索引,使之可以被搜尋)檢索引擎工具包(全文檢索引擎的架構),用於處理純文字的資料,提供建立索引、執行搜尋等介面,但不包含分散式服務。
Elasticsearch是近實時(新增到 ES 中的資料在1秒後就可以被檢索到,這種新增資料對搜尋的可見性稱為“準實時搜尋”)的分散式搜尋分析引擎,內部使用Lucene做索引與搜尋。ES分散式意味著可以動態調整叢集規模,彈性擴容,從官方的描述,叢集規模支援“上百”個節點。因此,目前認為ES適合中等資料量的業務,不適合儲存海量資料。
基於ES可以很容易地搭建自己的搜尋引擎,用於分析日誌,或者建立某個垂直領域的搜尋引擎。此外,ES 還提供了大量的聚合功能,所以它不單單是一個搜尋引擎,還可以進行資料分析、統計,生成指標資料。
2、常用概念
2.1)索引詞(term)
在Elasticsearch中索引詞(term)是一個能夠被索引的精確值。索引詞(term)是可以通過term查詢進行準確搜尋。
2.2)文字(text)
文字是一段普通的非結構化文字。文字會被分析成一個個的索引詞,儲存在Elasticsearch的索引庫中。為了讓文字能夠進行搜尋,文字欄位需要事先進行分析;當對文字中的關鍵詞進行查詢的時候,搜尋引擎應該根據搜尋條件搜尋出原文字。
引申:keyword,儲存資料時候,不會分詞建立索引。
2.3)分析(analysis)
分析是將文字轉換為索引詞的過程,分析的結果依賴於分詞器。比如:FOO BAR、Foo-Bar和foo bar這幾個單詞有可能會被分析成相同的索引詞foo和bar,這些索引詞儲存在Elasticsearch的索引庫中。當用FoO:bAR進行全文搜尋的時候,搜尋引擎根據匹配計算也能在索引庫中搜尋出之前的內容。這就是Elasticsearch的搜尋分析。
2.4)索引(index)
索引是具有相同結構的文件集合。例如,可以有一個客戶資訊的索引,包括一個產品目錄的索引,一個訂單資料的索引。在系統上索引的名字全部小寫,通過這個名字可以用來執行索引、搜尋、更新和刪除操作等。在單個叢集中,可以定義多個索引。
es索引結構如圖
型別(type)
在索引中,可以定義一個或多個型別,型別是索引的邏輯分割槽。在一般情況下,一種型別被定義為具有一組公共欄位的文件。例如,假設執行一個部落格平臺,並把所有的資料儲存在一個索引中。在這個索引中,可以定義一種型別為使用者資料,一種型別為部落格資料,另一種型別為評論資料。
2.5)文件(document)
文件是儲存在Elasticsearch中的一個JSON格式的字串。它就像在關聯式資料庫中表的一行。每個儲存在索引中的一個文件都有一個型別和一個ID,每個文件都是一個JSON物件,儲存了零個或者多個欄位,或者鍵值對。
注意:原始的JSON文件被儲存在一個_source的欄位中。當搜尋文件的時候預設返回的就是這個欄位。
2.6)對映(mapping)
對映像關聯式資料庫中的表結構,每一個索引都有一個對映,它定義了索引中的每一個欄位型別,以及一個索引範圍內的設定。一個對映可以事先被定義,或者在第一次儲存文件的時候自動識別。
2.7)欄位(field)
文件中包含零個或者多個欄位,欄位可以是一個簡單的值(例如字串、整數、日期),也可以是一個陣列或物件的巢狀結構。欄位類似於關聯式資料庫中表的列。每個欄位都對應一個欄位型別,例如整數、字串、物件等。欄位還可以指定如何分析該欄位的值。
2.8)來源欄位(source field)
預設情況下,原文件將被儲存在_source這個欄位中,查詢的時候也是返回這個欄位。可以從搜尋結果中訪問原始的物件,這個物件返回一個精確的JSON字串,不顯示索引分析後的其他任何資料。
2.9)主鍵(ID)
ID是一個檔案的唯一標識,如果在存庫的時候沒有提供ID,系統會自動生成一個ID,文件的index/type/id必須是唯一的。
2.10)對映(mapping)
對映是定義文件及其包含的欄位如何儲存和索引的過程。
使用對映通常定義:
- 哪些字串欄位應被視為全文欄位。
- 哪些欄位包含數字、日期或地理位置。
- 日期值的格式。
- 自定義規則來控制動態新增欄位的對映 。
- (1)元欄位
_index
,_type
, _id
,和_source
領域。每個文件都有與其關聯的後設資料,例如_index
、 mapping _type
和_id
元欄位。建立對映型別時,可以自定義其中一些元欄位的行為。_source
表示文件正文的原始 JSON。_size
_source
由mapper-size
外掛提供 的欄位大小(以位元組為單位) 。 _field_names
文件中包含非空值的所有欄位。_ignored
文件中由於 ignore_malformed
. _routing
將文件路由到特定分片的自定義路由值。
- (2)欄位或屬性
properties
與文件相關的欄位列表。欄位資料型別每個欄位都有一個資料type
- 一個簡單的型別,如
text
,keyword
,date
,long
,double
,boolean或
ip
。 - 一種支援 JSON 分層性質的型別,例如
object
或nested
。 - 或特殊型別,如
geo_point
,geo_shape
, 或completion
。
string
欄位可以被索引為一個text,
用於全文搜尋的keyword
欄位,以及一個用於排序或聚合的欄位。這就是多欄位的目的,大多數資料型別通過fields
引數支援多欄位。補充:
1)、防止對映爆炸的設定
在索引中定義太多欄位會導致對映爆炸,從而導致記憶體不足錯誤和難以恢復的情況。例如,考慮這樣一種情況,插入的每個新文件都會引入新欄位。每次文件包含新欄位時,這些欄位都會追加在在索引的對映中,隨著對映的增長,可能會成為一個問題。以下設定限制可以手動或動態建立的欄位對映的數量,以防止不良文件導致對映爆炸:
index.mapping.total_fields.limit
索引中的最大欄位數。欄位和物件對映以及欄位別名計入此限制。預設值為1000
。(限制是為了防止對映和搜尋變得太大。較高的值會導致效能下降和記憶體問題,尤其是在負載高或資源少的叢集中。如果增加此設定,建議也增加該 indices.query.bool.max_clause_count
設定,這會限制查詢中布林子句的最大數量。)
index.mapping.depth.limit
最大深度,以內部物件的數量來衡量。例如,如果所有欄位都在根物件級別定義,則深度為1
。如果有一個物件對映,則深度為 2
等。預設為20
。 index.mapping.nested_fields.limit
nested
索引 中不同對映的最大數量,預設為50
。index.mapping.nested_objects.limit
nested
單個文件中所有巢狀型別 的最大JSON 物件數,預設為 10000。
index.mapping.field_name_length.limit
設定欄位名稱的最大長度。預設值為 Long.MAX_VALUE(無限制)。此設定並不是真正解決對映爆炸的問題,但如果限制欄位長度,它可能仍然有用。通常不需要設定此設定。除非使用者開始新增大量名稱非常長的欄位,否則預設值是可以的。
2)、mapping設定
2.1)mapping中的欄位型別一旦設定,一旦已經有資料寫入,禁止直接修改,因為 lucene實現的倒排索引生成後不允許修改(但是可以新增欄位),應該重新建立新的索引,然後做reindex操作。
1. 新增加欄位
- Dynamic設為true時,一旦有新增欄位的文件寫入,Mapping也會同時被更新;
- Dynamic設為false,Mapping不會被更新,新增欄位的資料無法被索引,但是資訊會出現在_source中;
- Dynamic設定成strict,文件寫入失敗。
2. 如果希望修改欄位型別,必須Reindex API,重建索引,因為如果修改了欄位的資料型別,會導致已被索引的無法被搜尋,但是如果是新增加的欄位,就不會有這樣的影響。
2.2)Dynamic Mapping
- 寫入文件時候,如果索引不存在,會自動建立索引;
- Dynamic Mapping機制,使得我們無需手動定義Mappings。Elasticsearch會自動根據文件資訊推算出欄位的型別;
- 若自動推算的不對,例如地理位置資訊,數值型別等,會導致部分函式無法使用(range等)。
二、常用用法
1、響應過濾
所有 REST API 都接受一個filter_path
引數,該引數可用於減少 Elasticsearch 返回的響應。此引數採用逗號分隔的過濾器列表,用點表示法表示:
eg1:
curl -X GET "localhost:9200/_search?q=elasticsearch&filter_path=took,hits.hits._id,hits.hits._score&pretty"
結果
{
"took" : 3,
"hits" : {
"hits" : [
{
"_id" : "0",
"_score" : 1.6375021
}
]
}
}
eg2:
curl -X GET "localhost:9200/_cluster/state?filter_path=metadata.indices.*.stat*&pretty"
{
"metadata" : {
"indices" : {
"twitter": {"state": "open"}
}
}
}
eg3:
curl -X GET "localhost:9200/_cluster/state?filter_path=routing_table.indices.**.state&pretty"
{
"routing_table": {
"indices": {
"twitter": {
"shards": {
"0": [{"state": "STARTED"}, {"state": "UNASSIGNED"}]
}
}
}
}
}
eg4:
curl -X GET "localhost:9200/_count?filter_path=-_shards&pretty"
{
"count" : 5
}
eg5:
curl -X GET "localhost:9200/_cluster/state?filter_path=metadata.indices.*.state,-metadata.indices.logstash-*&pretty"
{
"metadata" : {
"indices" : {
"index-1" : {"state" : "open"},
"index-2" : {"state" : "open"},
"index-3" : {"state" : "open"}
}
}
}
eg6:
Elasticsearch 有時會直接返回欄位的原始值,例如_source
欄位。如果要過濾_source
欄位,應考慮將現有_source
引數與如下filter_path
引數組合使用:
curl -X POST "localhost:9200/library/book?refresh&pretty" -H 'Content-Type: application/json' -d'
{"title": "Book #1", "rating": 200.1}
'
curl -X POST "localhost:9200/library/book?refresh&pretty" -H 'Content-Type: application/json' -d'
{"title": "Book #2", "rating": 1.7}
'
curl -X POST "localhost:9200/library/book?refresh&pretty" -H 'Content-Type: application/json' -d'
{"title": "Book #3", "rating": 0.1}
'
curl -X GET "localhost:9200/_search?filter_path=hits.hits._source&_source=title&sort=rating:desc&pretty"
{
"hits" : {
"hits" : [ {
"_source":{"title":"Book #1"}
}, {
"_source":{"title":"Book #2"}
}, {
"_source":{"title":"Book #3"}
} ]
}
}
備註:&pretty 表示返回結果以json格式美化展示。
2、啟用堆疊跟蹤
預設情況下,當請求返回錯誤時,Elasticsearch 不包括錯誤的堆疊跟蹤。通過將error_trace在
url 引數設定為 true
。
eg,預設情況下,向API傳送無效size
引數時_search
:
curl -X POST "localhost:9200/twitter/_search?size=surprise_me&pretty"
{
"error" : {
"root_cause" : [
{
"type" : "illegal_argument_exception",
"reason" : "Failed to parse int parameter [size] with value [surprise_me]"
}
],
"type" : "illegal_argument_exception",
"reason" : "Failed to parse int parameter [size] with value [surprise_me]",
"caused_by" : {
"type" : "number_format_exception",
"reason" : "For input string: \"surprise_me\""
}
},
"status" : 400
}
設定error_trace=true
:
curl -X POST "localhost:9200/twitter/_search?size=surprise_me&error_trace=true&pretty"
{
"error": {
"root_cause": [
{
"type": "illegal_argument_exception",
"reason": "Failed to parse int parameter [size] with value [surprise_me]",
"stack_trace": "Failed to parse int parameter [size] with value [surprise_me]]; nested: IllegalArgumentException..."
}
],
"type": "illegal_argument_exception",
"reason": "Failed to parse int parameter [size] with value [surprise_me]",
"stack_trace": "java.lang.IllegalArgumentException: Failed to parse int parameter [size] with value [surprise_me]\n at org.elasticsearch.rest.RestRequest.paramAsInt(RestRequest.java:175)...",
"caused_by": {
"type": "number_format_exception",
"reason": "For input string: \"surprise_me\"",
"stack_trace": "java.lang.NumberFormatException: For input string: \"surprise_me\"\n at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)..."
}
},
"status": 400
}
3、文件操作
(3.1)插入json文件到索引
eg1:
(1)將 JSON 文件插入twitter
索引中,索引_id
值為 1:
curl -X PUT "localhost:9200/twitter/_doc/1?pretty" -H 'Content-Type: application/json' -d'
{
"user" : "kimchy",
"post_date" : "2009-11-15T14:12:12",
"message" : "trying out Elasticsearch"
}
'
"_shards" : {
"total" : 2,
"failed" : 0,
"successful" : 2
},
"_index" : "twitter",
"_type" : "_doc",
"_id" : "1",
"_version" : 1,
"_seq_no" : 0,
"_primary_term" : 1,
"result" : "created"
}
(2)如果不存在具有該 ID 的文件,則使用該_create
資源將文件索引到twitter
索引中:
curl -X PUT "localhost:9200/twitter/_create/1?pretty" -H 'Content-Type: application/json' -d'
{
"user" : "kimchy",
"post_date" : "2009-11-15T14:12:12",
"message" : "trying out Elasticsearch"
}
'
(3)如果不存在具有該 ID 的文件,則設定op_type
要建立的引數以將文件索引到twitter
索引中:
curl -X PUT "localhost:9200/twitter/_doc/1?op_type=create&pretty" -H 'Content-Type: application/json' -d'
{
"user" : "kimchy",
"post_date" : "2009-11-15T14:12:12",
"message" : "trying out Elasticsearch"
}
'
eg2:_id
從twitter
索引中檢索0的 JSON 文件
curl -X GET "localhost:9200/twitter/_doc/0?pretty"
{
"_index" : "twitter",
"_type" : "_doc",
"_id" : "0",
"_version" : 1,
"_seq_no" : 10,
"_primary_term" : 1,
"found": true,
"_source" : {
"user" : "kimchy",
"date" : "2009-11-15T14:12:12",
"likes": 0,
"message" : "trying out Elasticsearch"
}
}
檢查是否_id
存在帶有0的文件:
curl -I "localhost:9200/twitter/_doc/0?pretty"
Elasticsearch 返回200 - OK
文件是否存在 的狀態碼404 - Not Found
。
(3.2)刪除文件
從twitter
索引中刪除 JSON 文件:
curl -X DELETE "localhost:9200/twitter/_doc/1?pretty"
{
"_shards" : {
"total" : 2,
"failed" : 0,
"successful" : 2
},
"_index" : "twitter",
"_type" : "_doc",
"_id" : "1",
"_version" : 2,
"_primary_term": 1,
"_seq_no": 5,
"result": "deleted"
}
(3.2.1)路由
如果在索引時使用路由,則還需要指定路由值才能刪除文件。如果_routing
對映設定為required
並且未指定路由值,則刪除 API 會丟擲 RoutingMissingException
並拒絕請求。
curl -X DELETE "localhost:9200/twitter/_doc/1?routing=kimchy&pretty"
補充:es路由機制
Elasticsearch的路由機制即是通過雜湊演算法,將具有相同雜湊值的文件放置到同一個主分片中(預設的路由演算法:將文件的ID值作為依據將其雜湊對映到相應的主分片上,這種演算法基本上會保持所有資料在所有分片上的一個平均分佈,而不會產生資料熱點。)。類似於通過雜湊演算法來進行負載均衡。指定路由的目的是將文件儲存到對應的分片上。
(3.2.2)超時
執行刪除操作時,分配用於執行刪除操作的主分片可能不可用。造成這種情況的一些原因可能是主分片當前正在從儲存中恢復或正在進行重新定位。預設情況下,刪除操作將等待主分片變為可用狀態長達 1 分鐘,然後才會失敗並響應錯誤。該timeout
引數可用於明確指定等待的時間。以下是將其設定為 5 分鐘的示例:
curl -X DELETE "localhost:9200/twitter/_doc/1?timeout=5m&pretty"
(3.2.3)刪除與指定查詢匹配的文件
curl -X POST "localhost:9200/twitter/_delete_by_query?pretty" -H 'Content-Type: application/json' -d'
{
"query": {
"match": {
"message": "some message"
}
}
}
'
(3.2.4)從twitter
索引中刪除所有推文
curl -X POST "localhost:9200/twitter/_delete_by_query?conflicts=proceed&pretty" -H 'Content-Type: application/json' -d'
{
"query": {
"match_all": {}
}
}
'
(3.2.5)從多個索引中刪除文件
curl -X POST "localhost:9200/twitter,blog/_delete_by_query?pretty" -H 'Content-Type: application/json' -d'
{
"query": {
"match_all": {}
}
}
'
(3.2.6)將按查詢刪除操作限制為特定路由值的分片
curl -X POST "localhost:9200/twitter/_delete_by_query?routing=1&pretty" -H 'Content-Type: application/json' -d'
{
"query": {
"range" : {
"age" : {
"gte" : 10
}
}
}
}
'
預設情況下_delete_by_query
使用 1000 的滾動批次。(使用scroll_size
URL 引數更改批次大小)
curl -X POST "localhost:9200/twitter/_delete_by_query?scroll_size=5000&pretty" -H 'Content-Type: application/json' -d'
{
"query": {
"term": {
"user": "kimchy"
}
}
}
'
(3.3)更新文件
向現有文件新增了一個新欄位:
curl -X POST "localhost:9200/test/_update/1?pretty" -H 'Content-Type: application/json' -d'
{
"doc" : {
"name" : "new_name"
}
}
'
4、快取
預設情況下,清除快取 API 會清除所有快取。可通過以下引數的設定來指定清楚執行快取:
fielddata
query
request
curl -X POST "localhost:9200/twitter/_cache/clear?fielddata=true&pretty"
curl -X POST "localhost:9200/twitter/_cache/clear?query=true&pretty"
curl -X POST "localhost:9200/twitter/_cache/clear?request=true&pretty"
fields
查詢引數。
curl -X POST "localhost:9200/twitter/_cache/clear?fields=foo,bar&pretty"
curl -X POST "localhost:9200/kimchy,elasticsearch/_cache/clear?pretty"
curl -X POST "localhost:9200/_cache/clear?pretty"
curl -X PUT "localhost:9200/twitter?pretty" -H 'Content-Type: application/json' -d'
{
"settings" : {
"index" : {
"number_of_shards" : 3,
"number_of_replicas" : 2
}
}
}
'
curl -X PUT "localhost:9200/twitter?pretty" -H 'Content-Type: application/json' -d'
{
"settings" : {
"number_of_shards" : 3,
"number_of_replicas" : 2
}
}
'
curl -X PUT "localhost:9200/test?pretty" -H 'Content-Type: application/json' -d'
{
"settings" : {
"number_of_shards" : 1
},
"mappings" : {
"properties" : {
"field1" : { "type" : "text" }
}
}
}
'
curl -X PUT "localhost:9200/test?pretty" -H 'Content-Type: application/json' -d'
{
"aliases" : {
"alias_1" : {},
"alias_2" : {
"filter" : {
"term" : {"user" : "kimchy" }
},
"routing" : "kimchy"
}
}
}
'
{
"acknowledged": true,
"shards_acknowledged": true,
"index": "test"
}
acknowledged
指示是否在叢集中成功建立索引,同時 shards_acknowledged
指示是否在超時之前為索引中的每個分片啟動了所需數量的分片副本。acknowledged
或 shards_acknowledged
是false
,但索引建立成功了。這些值僅指示操作是否在超時之前完成。如果 acknowledged
是false
,表示我們在使用新建立的索引更新叢集狀態之前就超時了,但它可能很快就會被建立。如果shards_acknowledged
是false
,表示我們在啟動所需數量的分片之前超時(預設情況下只是主分片),即使叢集狀態已成功更新以反映新建立的索引(即acknowledged=true
)。index.write.wait_for_active_shards
(更改此設定也會影響wait_for_active_shards
後續所有寫入操作的值):
curl -X PUT "localhost:9200/test?pretty" -H 'Content-Type: application/json' -d'
{
"settings": {
"index.write.wait_for_active_shards": "2"
}
}
'
wait_for_active_shards
:
curl -X PUT "localhost:9200/test?wait_for_active_shards=2&pretty"
curl -X DELETE "localhost:9200/twitter?pretty"
curl -X DELETE "localhost:9200/twitter/_alias/alias1?pretty"
curl -X POST "localhost:9200/kimchy/_flush?pretty"
curl -X POST "localhost:9200/kimchy,elasticsearch/_flush?pretty"
curl -X POST "localhost:9200/_flush?pretty"
curl -X GET "localhost:9200/twitter?pretty"
curl -X GET "localhost:9200/logs_20302801/_alias/*?pretty"
{
"logs_20302801" : {
"aliases" : {
"current_day" : {
},
"2030" : {
"filter" : {
"term" : {
"year" : 2030
}
}
}
}
}
}
(5.5)索引別名操作
(5.5.1)建立或更新索引別名
索引別名是用於引用一個或多個現有索引的輔助名稱(大多數 Elasticsearch API 接受索引別名來代替索引名稱)。
curl -X PUT "localhost:9200/twitter/_alias/alias1?pretty"
eg:請求2030
為logs_20302801
索引建立別名
curl -X PUT "localhost:9200/logs_20302801/_alias/2030?pretty"
新增基於使用者的別名
eg:
(1)建立一個索引users
,帶有user_id
欄位的對映
curl -X PUT "localhost:9200/users?pretty" -H 'Content-Type: application/json' -d' { "mappings" : { "properties" : { "user_id" : {"type" : "integer"} } } } '
(2)為特定使用者新增索引別名,user_12
:
curl -X PUT "localhost:9200/users/_alias/user_12?pretty" -H 'Content-Type: application/json' -d' { "routing" : "12", "filter" : { "term" : { "user_id" : 12 } } } '
(5.5.2)建立索引時新增別名
eg:使用create index API 在索引建立過程中新增索引別名
curl -X PUT "localhost:9200/logs_20302801?pretty" -H 'Content-Type: application/json' -d' { "mappings" : { "properties" : { "year" : {"type" : "integer"} } }, "aliases" : { "current_day" : {}, "2030" : { "filter" : { "term" : {"year" : 2030 } } } } } '
curl -X GET "localhost:9200/_alias/2030?pretty"
{
"logs_20302801" : {
"aliases" : {
"2030" : {
"filter" : {
"term" : {
"year" : 2030
}
}
}
}
}
}
curl -X GET "localhost:9200/_alias/20*?pretty"
{
"logs_20302801" : {
"aliases" : {
"2030" : {
"filter" : {
"term" : {
"year" : 2030
}
}
}
}
}
}
curl -X GET "localhost:9200/twitter,kimchy/_settings?pretty"
curl -X GET "localhost:9200/_all/_settings?pretty"
curl -X GET "localhost:9200/log_2013_*/_settings?pretty"
curl -X GET "localhost:9200/log_2013_-*/_settings/index.number_*?pretty"
curl -X GET "localhost:9200/_template/template_1,template_2?pretty"
curl -X GET "localhost:9200/_template/temp*?pretty"
curl -X GET "localhost:9200/_template?pretty"
curl -X GET "localhost:9200/twitter,kimchy/_mapping?pretty"
curl -X GET "localhost:9200/_all/_mapping?pretty"
curl -X GET "localhost:9200/_mapping?pretty"
curl -X PUT "localhost:9200/library/book/_bulk?refresh&pretty" -H 'Content-Type: application/json' -d' {"index":{"_id": "Leviathan Wakes"}} {"name": "Leviathan Wakes", "author": "James S.A. Corey", "release_date": "2011-06-02", "page_count": 561} {"index":{"_id": "Hyperion"}} {"name": "Hyperion", "author": "Dan Simmons", "release_date": "1989-05-26", "page_count": 482} {"index":{"_id": "Dune"}} {"name": "Dune", "author": "Frank Herbert", "release_date": "1965-06-01", "page_count": 604} '
使用SQL REST API執行 SQL :
curl -X POST "localhost:9200/_sql?format=txt&pretty" -H 'Content-Type: application/json' -d' { "query": "SELECT * FROM library WHERE release_date < \u00272000-01-01\u0027" } '
返回結果
author | name | page_count | release_date ---------------+---------------+---------------+------------------------ Dan Simmons |Hyperion |482 |1989-05-26T00:00:00.000Z Frank Herbert |Dune |604 |1965-06-01T00:00:00.000Z
結構化查詢(Query DSL): query的時候,會先比較查詢條件,然後計算分值,最後返回文件結果;
結構化過濾(Filter DSL): 過濾器,對查詢結果進行快取,不會計算相關度,避免計算分值,執行速度非常快(推薦使用);
1)結構化過濾(Filter DSL)【 6種過濾 】
term 過濾:term 主要用於精確匹配哪些值,比如數字,日期,布林值或 not_analyzed 的字串(未經分析的文字 資料型別),相當於sql age=26
{ "term": { "age": 26 }}
{ "term": { "date": "2014-09-01" }}
terms 過濾:terms 允許指定多個匹配條件。如果某個欄位指定了多個值,那麼文件需要一起去做匹配。相當於sql: in 查詢
{"terms": {"age": [26, 27, 28]}}
range 過濾:range 過濾允許我們按照指定範圍查詢一批資料,相等於sql between
{ "range": { "price": { "gte": 2000, "lte": 3000 } } } gt : 大於 lt : 小於 gte : 大於等於 lte :小於等於
exists 和 missing 過濾:exists 和 missing 過濾可以用於查詢文件中是否包含指定欄位或沒有某個欄位,類似於SQL語句中的 IS_NULL條件
{ "exists": { "field": "title" } }
bool 過濾:用來合併多個過濾條件查詢結果的布林邏輯;
must:多個查詢條件的完全匹配,相當於 and。
must_not: 多個查詢條件的相反匹配,相當於 not;
should:至少有一個查詢條件匹配,相當於 or; 相當於sql and 和or
{ "bool": { "must": { "term": { "folder": "inbox" } }, "must_not": { "term": { "tag": "spam" } }, "should": [{ "term": { "starred": true } }, { "term": { "unread": true } }] } }
2)結構化查詢(Query DSL)
bool 查詢:bool 查詢與 bool 過濾相似,用於合併多個查詢子句。不同的是,bool 過濾可以直接給出是否匹配成功, 而bool 查詢要計算每一個查詢子句的 _score
{ "bool": { "must": { "match": { "title": "how to make millions" } }, "must_not": { "match": { "tag": "spam" } }, "should": [{ "match": { "tag": "starred" } }, { "range": { "date": { "gte": "2014-01-01" } } }] } }
bool巢狀查詢
{ "bool": { "should": [{ "term": { "productID": "KDKE-B-9947-#kL5" } }, { "bool": { "must": [{ "term": { "productID": "JODL-X-1937-#pV7" } }, { "term": { "price": 30 } }] } }] } }
match_all 查詢:使用match_all 可以查詢到所有文件,是沒有查詢條件下的預設語句。
{
"match_all": {}
}
match 查詢:match查詢是一個標準查詢,不管你需要全文字查詢還是精確查詢基本上都要用到它。 如果你使用 match 查詢一個全文字欄位,它會在真正查詢之前用分析器先分析match一下查詢字元
{ "match": { "tweet": "About Search" } }
multi_match 查詢:multi_match查詢允許你做match查詢的基礎上同時搜尋多個欄位
{ "multi_match": { "query": "full text search", "fields": ["title", "body"] } }
match_phrase:短語查詢,full text search 是一個片語,意味著三個詞的位置是連續且有順序
{ "match_phrase": { "title": "full text search", } }
設定slop片語間隔
{ "match_phrase": { "title": { "query": "full text search", "slop": 1 } } }
phrase_prefix 查詢:與片語中最後一個詞條進行字首匹配。
{ "query": { "match_phrase_prefix": { "title": { "query": "傳智" } } }, "from": 0, "size": 5 }
regexp查詢:萬用字元查詢
{ "query": { "regexp": { "title": "W[0-9].+" } } }
過濾查詢:查詢語句和過濾語句可以放在各自的上下文中,filtered已棄用,用bool代替
{ "query": { "bool": { "must": { "match": { "text": "quick brown fox" } }, "filter": { "term": { "status": "published" } } } }"from": 0, #從0開始"size": 10, #顯示條數"sort": { "publish_date": { "order": "desc" } } }
官放文件地址:https://www.elastic.co/guide/en/elasticsearch/reference/7.4/elasticsearch-intro.html
感謝閱讀,如需轉載,請註明出處,謝謝!https://www.cnblogs.com/huyangshu-fs/p/11683905.html