大家好,我是Edison。首先說聲抱歉,這個ES學習系列很久沒更新了,現在繼續吧。
上一篇:ES的倒排索引和Analyzer
什麼是Query DSL
DSL是Domain Specific Language的縮寫,指的是爲特定問題領域設計的計算機語言。這種語言專注於某特定領域的問題解決,因而比通用編程語言更有效率。
在ElasticSearch中,DSL指的是Elasticsearch Query DSL,是一種以JSON形式表示的查詢語言。通過這種語言,用戶可以構建複雜的查詢、排序和過濾數據等操作。這些查詢可以是全文搜索、聚合搜索,也可以是結構化的搜索。
Elastic Query DSL的基本語法如下:
# 基本格式 GET /es_db/_doc/_search {json-request-body} # 簡化格式 GET /es_db/_search {json-request-body}
match_all
使用match_all就類似於SQL中的SELECT *了,它會匹配所有文檔,但默認只會返回10條數據。這是因爲,_search查詢默認採用的是分頁查詢,每頁size默認值就是10,因此如果想顯示更多,請制定size。
// 匹配所有文檔,默認分頁只返回10條 GET users/_search { "query": { "match_all":{} } } // 設置分頁的每頁條數size值爲20 GET users/_search { "query": { "match_all":{} }, "size": 20 }
分頁查詢 from & size & sort
分頁查詢最重要的3個參數:from 、size 和 sort。
from: 顯示應該跳過的初始結果數量,默認是0。
size: 顯示應該返回的結果數量,默認是10,剛剛有演示。
sort: 根據什麼字段 以及 升序 或 降序 來排序。
// 從第5個文檔開始取10個顯示,並根據用戶名升序排列 GET users/_search { "query": { "match_all":{} }, "sort": { "user": "asc" } "from": 5 "size": 20 }
_source 過濾
_source參數就好比SELECT field1, field2,當我們需要只查詢某些特定字段時,就可以使用_source參數來進行過濾。_source支持使用通配符,可以較爲方便的編寫,如:_source["name*","desc*"]。
# 只查詢users中的user和message兩個字段數據,過濾掉其他字段 GET users/_search { "_source": ["user","message"], "query": { "match_all":{} }, "from": 0, "size": 20 }
match 查詢表達式
match 查詢表達式可能是我們用的最多的參數了,它會在匹配時對所查找的關鍵詞進行分詞,然後按照分詞匹配查找。
match 支持以下參數:
-
query 指定匹配的值
-
operator 匹配條件類型
-
and 條件分詞後都要匹配
-
or 條件分詞後有一個匹配即可(默認的operator類型)
// 默認爲or => comments字段中有文檔出現任意一個Song or Last or Christmas GET comments/_search { "query": { "match": { "comment": { "query": "Song Last Christmas" } } } } // 手動指定and => comments字段中有文檔同時出現Song Last Christmas GET comments/_search { "query": { "match": { "comment": { "query": "Song Last Christmas", "operator": "and" } } } }
multi_match 多字段查詢表達式
上面演示的是針對單個字段的查詢,那麼如果想要針對多個字段查詢呢?
使用multi_match即可,指定fields:
GET comments/_search { "query": { "multi_match": { "query": "Song Last Christmas", "fields": ["comments", "address"] } } }
match_phrase 短語查詢表達式
短語查詢會對搜索文本進行文本分析,然後纔到索引中尋找搜索的每個分詞並要求分詞相鄰。我們可以通過slop參數設置分詞出現的最大間隔距離,可以通過下面的例子來看看。
// 查詢one love這個短語出現過的文檔 POST movies/_search { "query": { "match_phrase": { "title": { "query": "one love" } } } } // 只要one和love之間間隔不超過1個詞就都顯示出來 POST movies/_search { "query": { "match_phrase": { "title": { "query": "one love", "slop": 1 } } } }
搜索結果:One I Love
query_string 與 simple_query_string
Query String類似於URI Query,這種查詢方式的語法和我們在SQL中的WHERE語句就有些類似了,基於OR/AND/NOT等運算符來解析和拆分提供的查詢字符串,我們可以使用 Query String 查詢創建一個較爲複雜的搜索,其中可以包括通配符、跨多個字段的搜索等。
雖然用途廣泛,但是語法較爲嚴格,容易出錯,不推薦在日常查詢中使用。
// 查詢單個字段 GET /bank/_search { "query": { "query_string": { "default_field": "address", "query": "Chengdu AND Shuangliu" } } } // 查詢多個字段 GET /bank/_search { "query": { "query_string": { "fields": ["name", "address"], "query": "(Edison AND Zhou) OR (Chengdu AND Shuangliu)" } } }
Simple Query String 顧名思義 就是簡單版Query String,它類似於Query String但會忽略錯誤的語法。此外,它不支持AND OR NOT,會將它們當作字符串來處理。各個Term之間默認的關係是OR,但可以指定Operator來覆蓋。
// 默認operator是OR => 出現其一即可 Edison or Zhou GET /bank/_search { "query": { "simple_query_string": { "query": "Edison Zhou", "fields": ["name"] } } } // 覆蓋默認operator 改爲AND => 必須完整出現 Edison Zhou GET /bank/_search { "query": { "simple_query_string": { "query": "Edison Zhou", "fields": ["name"], "default_operator": "AND" } } }
小結
本篇,我們瞭解了ElasticSearch的Query DSL,並通過一些查詢示例瞭解瞭如何使用它。除了本文中介紹的部分高頻DSL外,你可以通過搜索閱讀其他的關鍵詞進行學習。
參考資料
極客時間,阮一鳴,《ElasticSearch核心技術與實戰》