DSL: Domain Specific Language, 領域特定語言, 指的是專一於某個應用程序領域的、具備高度針對性的計算機語言.java
Query String 與 Query DSL之間的區別:面試
Query String: 在請求的URL後直接拼接查詢條件;
Query DSL: 在請求的Request Body中攜帶查詢條件.編程
DSL功能強大, 能夠構建複雜的查詢、過濾、聚合條件, 因此這種查詢方式的用途最廣.json
對於複雜的查詢, 頗有必要在查詢前使用validate API
進行驗證, 保證DSL語句的正確有效:併發
// 要查詢name中包含"java"的文檔: GET shop/it_book/_validate/query?explain { "query": { "math": { // 錯誤的查詢名稱, 應該是match "name": "java" } } } // 校驗結果: { "valid": false, "error": "org.elasticsearch.common.ParsingException: no [query] registered for [math]" } // 修改math爲match後, 校驗結果爲: { "valid": true, "_shards": { "total": 1, "successful": 1, "failed": 0 }, "explanations": [ { "index": "shop", "valid": true, // 校驗經過, DSL有效 "explanation": "+name:java #_type:it_book" // 查詢條件, +表示必須存在 } ] }
GET shop/it_book/_search { "query": { "match_all": {} } }
查詢name中包含"java"的文檔, 同時按照價格升序排序:elasticsearch
GET shop/it_book/_search { "query": { "match": { "name": "java" } }, "sort": [ { "price": {"order": "asc"} } ] }
GET shop/it_book/_search { "query": { "match_all": {} }, "from": 0, // 開始記錄數, 起始數爲0 "size": 1 // 頁大小, 即每頁顯示的記錄數 }
GET shop/it_book/_search { "query": { "match_all": {} }, "_source": [ "name", // 顯示商品名稱 "price" // 顯示商品價格 ] }
不一樣的數據類型在創建倒排索引時, 有的會做爲full text處理, 有的做爲exact value處理.this
對查詢串分詞時, 使用的分析器(analyzer)必須和建立index時使用的相同, 不然將檢索不到準確的數據..net
常見的exact value類型有date - 日期類型.code
ES檢索時, 不會對String進行分詞, 而是徹底根據String的值去精確匹配, 查找相應的文檔.
在DSL中, 經過match_phrase
短語匹配達到精確匹配的目的 —— 不會對查詢串進行分詞, 而是直接精確匹配查找.
示例: 查詢name中包含"thinking in java"的文檔, 不會對查詢串進行分詞:
GET shop/_search { "query": { "match_phrase": { "name": "thinking in java" } } }
常見的full text類型有: text - 文本串.
ES檢索時, 會對檢索串進行分詞, 包括縮寫、時態、同義詞等轉換手段, 而後根據分詞結果與倒排索引進行匹配, 查找相應的文檔.
索引中只要有任意一個相關field的分詞 匹配拆分後的詞, 這個文檔就能夠出如今結果中, 只是匹配度越高的排名越靠前.
示例: 查詢name中包含"thinking in java"的文檔, 會將查詢串拆分爲"think", "in", "java"三個詞:
GET shop/_search { "query": { "match": { "name": "thinking in java" } } }
operator
操做符, 用來指定ES對分詞後的詞項如何進行檢索過濾. 選項有:
and, 做用 == match_phrase, 即所有匹配;
or, 做用 == match, 即部分匹配.
使用示例:
GET shop/_search { "query": { "match": { "name": { // 要查詢的field "query": "編程思想", "operator": "or" // 操做符 } } } }
minimum_should_match
用來指定最少要匹配多少比例的分詞, 纔算符合條件並返回結果.
示例: 搜索name中包含"併發編程的藝術", 被拆分紅"併發", "編程", "藝術"等詞, 如今要求至少匹配50%的分詞, 能夠這樣:
GET shop/_search { "query": { "match": { "name": { "query": "併發編程的藝術", "minimum_should_match": "50%" } } } }
固然這種需求也能夠用 must、must_not、should 匹配同一個字段的方式進行組合查詢.
multi_match
用來對多個字段同時進行匹配: 任意一個字段中存在相應的分詞, 就可做爲結果返回.
示例 ① : 查詢 name 或 desc 字段中包含 "面試經典" 的文檔 —— 會對查詢串進行分詞:
GET shop/_search { "query": { "multi_match": { "query": "面試經典", "fields": [ "name", "desc" ] } } }
示例 ② : 查詢 name 或 desc 字段中同時包含 "面試經典" 的文檔 —— 不對查詢串進行分詞:
GET shop/_search { "query": { "multi_match": { "query": "面試經典", "type": "cross_fields", // 還有best_fields、most_fields、phrase、phrase_prefix選項 "operator": "and", // 所有匹配, or是部分匹配 "fields": [ "name", "desc" ] } } }
bool query, 顧名思義, 就是 真假/有無 查詢. 包括4個子查詢:
① must - 必須匹配, 相似於SQL中的
=
;
② must_not - 必須不匹配, 相似於SQL中的!=
;
③ should - 不強制匹配, 相似於SQL中的or
;
④ filter - 過濾, 將知足必定條件的文檔篩選出來.
除filter以外, 每一個子查詢都會根據本身的條件計算出每一個文檔的相關度分數, 而後bool綜合全部分數, 合併爲一個.
GET shop/_search { "query": { "bool": { "must":[ { "match": { "name": "Java" } } ], "must_not": [ { "match": { "desc": "編程" } } ], "should": [ { "match": { "publisher": "機械工業" } } ], "filter": { "bool": { "must": [ { "range": { "date": { "gte": "2010-01-01" }}}, { "range": { "price": { "lte": 99.00 }}} ] } } } } }
GET shop/_search { "query": { "bool": { "should": [ { "term": { "name.keyword": "Java編程思想" } }, { "bool": { "must": [ { "term": { "product_desc": "刷頭" } } ] } } ] } } }
若是不指定query條件而直接filter, 將拋出
no [query] registered for [filter]
, 此時經過constant_score
便可實現直接filter.
GET shop/_search { "query": { "constant_score": { "filter": { "range": { "price": { "gte": 80 } } } } } }
若是組合查詢中沒有must
, 就會至少匹配一個should
.
能夠經過 minimum_should_match
指定匹配的should
的個數.
GET shop/_search { "query": { "bool": { "should": [ { "match": { "name": "java" } }, { "match": { "desc": "編程"} }, { "match": { "price": 109 } } ], "minimum_should_match": 2 } } }
參考資料
版權聲明
出處: 博客園 馬瘦風的博客(https://www.cnblogs.com/shoufeng)
感謝閱讀, 若是文章有幫助或啓發到你, 點個[好文要頂👆] 或 [推薦👍] 吧😜
本文版權歸博主全部, 歡迎轉載, 但 [必須在文章頁面明顯位置標明原文連接], 不然博主保留追究相關人員法律責任的權利.