引言
雖然之前做過 elasticsearch 的項目,但是沒有對整個項目的知識點進行過系統的整理。這次趁着對 elasticsearch 版本的升級的機會(從2.2 升級到 6.3) ,又專門花時間對涉及到的知識點重新梳理了一遍。
俗話說,好記性不如爛筆頭。為了加深對 elasticsearch 的理解,后面再做類似項目時更容易撿起來,以及對用到的同學提供方便。從本文開始,我會對 elasticsearch Query DSL 的知識點進行梳理。
在講解時我會盡量以實例代碼展示的方式進行最直觀的展現。紙上來得終覺淺,絕知此事要躬行。做技術尤其要注重多實踐,懂了並不代表你就掌握了。強烈建議有志於深入了解這部分內容的同學,對文中給出的代碼實例在 sense 中實踐一遍甚至是多遍。
注意: 本文基於 elasticsearch 6.3 版本, 如果您使用的是其他版本,一些內容可能會有所變化,具體使用時還請以官方文檔為准
Query DSL 是 elasticsearch 的核心,搜索方面的項目大部分時間都耗費在對查詢結果的調優上。因此對 Query DSL 的理解越深入,越能節省項目時間,並給用戶好的體驗。
概要
Elasticsearch 提供了一個完整的 query DSL,並且是 JSON 形式的。它和 AST 比較類似,並且包含兩種類型的語句:
-
葉子查詢語句(Leaf Query)
用於查詢某個特定的字段,如
match
,term
或range
等 -
復合查詢語句 (Compound query clauses)
用於合並其他的葉查詢或復合查詢語句,也就是說復合語句之間可以嵌套,用來表示一個復雜的單一查詢
DSL (domain-specific language),領域特定語言指的是專注於某個應用程序領域的計算機語言,又譯作領域專用語言。不同於普通的跨領域通用計算機語言(GPL),領域特定語言只用在某些特定的領域。
AST(abstract syntax tree), 抽象語法樹是源代碼的抽象語法結構的樹形表現形式。樹上的每個節點都表示源代碼中的一種結構。之所以說語法是“抽象”的,是因為這里的語法並不會表示出真實語法中出現的每個細節。比如,嵌套括號被隱含在樹的結構中,並沒有以節點的形式呈現;而類似於if-condition-then這樣的條件跳轉語句,可以使用帶有兩個分支的節點來表示。
——百度百科
Query and filter context
一個查詢語句究竟具有什么樣的行為和得到什么結果,主要取決於它到底是處於查詢上下文(Query Context) 還是過濾上下文(Filter Context)。兩者有很大區別,我們來看下:
-
Query context 查詢上下文
這種語句在執行時既要計算文檔是否匹配,還要計算文檔相對於其他文檔的匹配度有多高,匹配度越高,_score 分數就越高
-
Filter context 過濾上下文
過濾上下文中的語句在執行時只關心文檔是否和查詢匹配,不會計算匹配度,也就是得分。
下面來看一個例子
GET /_search
{
"query": {
"bool": {
"must": [
{ "match": { "title": "Search" }},
{ "match": { "content": "Elasticsearch" }}
],
"filter": [
{ "term": { "status": "published" }},
{ "range": { "publish_date": { "gte": "2015-01-01" }}}
]
}
}
}
對上面的例子分析下:
query
參數表示整個語句是處於 query context 中bool
和match
語句被用在 query context 中,也就是說它們會計算每個文檔的匹配度(_score)filter
參數則表示這個子查詢處於 filter context 中filter
語句中的term
和range
語句用在 filter context 中,它們只起到過濾的作用,並不會計算文檔的得分。
Match All Query
這個查詢最簡單,所有的 _score
都是 1.0。
GET /_search
{
"query": {
"match_all": {}
}
}
它的反面就是 Match None Query, 匹配不到任何文檔(不知道用它來做什么……)
GET /_search
{
"query": {
"match_none": {}
}
}
全文查詢 Full text queries
全文本查詢的使用場合主要是在出現大量文字的場合,例如 email body 或者文章中搜尋出特定的內容。
全文查詢主要分為下面幾種(此處列表中的鏈接為官方文檔鏈接,后續將各部分講解后,會替換為講解鏈接):
-
全文查詢中最主要的查詢,包括模糊查詢(fuzzy matching) 或者臨近查詢(proximity queries)。
-
和
match
查詢比較類似,但是它會保留包含所有搜索詞項,且位置與搜索詞項相同的文檔。 -
是一種輸入即搜索(search-as-you-type) 的查詢,它和
match_phrase
比較類似,區別就是會將查詢字符串的最后一個詞作為前綴來使用。 -
多字段版本的
match
query -
只知道是一種特殊的查詢,具體干什么還不清楚,后面弄明白后會再來補充。
-
支持復雜的 Lucene query String 語法,除非你是專家用戶,否則不推薦使用。
-
簡化版的
query_string
,語法更適合用戶操作。
小結
本文主要講解了 elasticsearch es 6.3 版本的 Query DSL 概要,Match All Query ,
全文查詢概要等內容。下篇會介紹全文查詢中的 Match 語句,敬請期待。