目錄javascript
term query
: 把檢索串看成一個總體來執行檢索, 即不會對檢索串分詞.java
term是徹底匹配檢索, 要用在不分詞的字段上, 若是某個field在映射中被分詞了, term檢索將不起做用.
因此, 不分詞的field, 要在mapping中設置爲不分詞.web
—— ES 5.x以後, 爲每一個text類型的字段新增了名爲keyword的子字段, 是不分詞的, 默認保留256個字符.編程
—— 可使用keyword字段進行term檢索. 示例:json
GET shop/_search { "query": { "term": { "name.keyword": "Java編程思想" } } }
terms
, 至關於多個term
檢索, 相似於SQL中in關鍵字的用法, 即在某些給定的數據中檢索:併發
GET shop/_search { "query": { "terms": { "name.keyword": [ "Java編程思想", "Java併發編程的藝術" ] } } }
prefix query
, 就是前綴檢索. 好比商品name中有多個以"Java"開頭的document, 檢索前綴"Java"時就能檢索到全部以"Java"開頭的文檔.app
—— 掃描全部倒排索引, 性能較差.post
GET shop/_search { "query": { "prefix": { "name": "java" } } }
掃描全部倒排索引, 性能較差.性能
GET shop/_search { "query": { "wildcard": { "name": "ja*" } } }
掃描全部倒排索引, 性能較差.this
GET shop/_search { "query": { "regexp": { "name": "jav[a-z]*" } } }
fuzziness
的默認值是2 —— 表示最多能夠糾錯兩次.
說明: fuzziness
的值太大, 將削弱檢索條件的做用, 也就是說糾錯次數太多, 就會致使限定檢索結果的檢索條件被改變, 失去了限定做用.
示例: 檢索name中包含"Java"的文檔, Java中缺失了一個字母a:
GET shop/_search { "query": { "match": { "name": { "query": "Jav", "fuzziness": 1, "operator": "and" } } } }
經過boost參數, 令知足某個條件的文檔的得分更高, 從而使得其排名更靠前.
GET shop/_search { "query": { "bool": { "must": [ { "match": { "name": "編程思想"} } ], "should": [ { "match": { "name": { "query": "藝術", "boost": 2 // 提高評分權重 } } } ] } } }
通常檢索中, 檢索條件會被分詞, bool檢索構建多個子檢索 (must
| must_not
| should
| filter
), 這些子檢索可能會包含多個field. 這時:
多個子檢索的field各自匹配少許關鍵字的文檔的分數 > 某個子檢索的field匹配大量關鍵字的文檔的分數.
若是咱們但願檢索結果中 (檢索串被分詞後的) 關鍵字匹配越多, 這樣的文檔就越靠前, 而不是多個子檢索中匹配少許分詞的文檔靠前.
⇒ 此時可使用dis_max和tie_breaker.
tie_breaker的值介於0~1之間, Elasticsearch將
bool檢索的分數 * tie_breaker
的結果與dis_max的最高分進行比較, 除了取dis_max的最高分之外, 還會考慮其餘的檢索結果的分數.
爲了增長精準度, 經常使用的是配合boost、minimum_should_match等參數控制檢索結果.
GET shop/_search { "query": { "dis_max": { "queries": [ { "match": { "name": "虛擬機" } }, { "match": { "desc": "經典" } } ], "tie_breaker": 0.2 // 對同時知足的文檔的分值進行提高 } } } GET shop/_search { "query": { "dis_max": { "queries": [ { "match": { "name": { "query": "虛擬機", "minimum_should_match": "50%", "boost": 2 } } }, { "match": { "desc": { "query": "經典", "minimum_should_match": "50%", "boost": 3 } } } ], "tie_breaker": 0.3 } } }
這是Elasticsearch 2.x中的API, 後續版本再也不支持.
檢索出版時間在2012-07以後, 且至少知足下述條件中一個的文檔:
a. 名稱(name)中包含"併發";
b. 描述(desc)中包含"java";
c. 出版社(publisher)名稱中不包含"電子".
GET shop/_search { "query": { "bool": { "filter": { // 按時間過濾 "range": { "date": {"gte": "2012-07"} } }, "should": [ // 可匹配, 可不匹配 { "match": { "name": "併發" } }, { "bool": { "must": { // 必須匹配 "match": { "desc": "java" } }, "must_not": { // 不能匹配 "match": { "publisher": "電子" } } } } ], "minimum_should_match": 1 // 至少知足should中的一個條件 } }, // 自定義排序 "sort": [ { "price": { "order": "desc" } } ] }
注意: 排序的字段最好是數字, 或日期, 由於字符串字段會被分詞, ES會經過分詞後的某個詞去排序, 結果難以預測.
匹配檢索: name中包含"java"卻不包含"虛擬機";
範圍檢索: 價格大於50、小於80;
結果排序: 按照價格升序排序.
GET shop/_search { "query": { "bool": { "must": { // 必須匹配 "match": { "name": "java" } }, "must_not": { // 必須不匹配 "match": { "name": "虛擬機" } }, "filter": { "range": { "price": { "gte": 40, "lte": 80, "boost": 2.0 // 設置得分的權重值(提高值), 默認是1.0 } } } } } }
關於範圍檢索的使用, 請參考下篇文章: ES 22 - Elasticsearch對數值或日期類型進行範圍檢索
(1) 默認排序規則:
ES默認是按檢索結果的分值(_score)降序排列的.
某些狀況下, 可能存在無實際意義的_score, 好比filter時全部_score的值都相同:
GET website/_search { "query": { "bool": { "filter": { "term": { "author_id": 5520 // 此時全部符合條件的_score都爲0 } } } } } // 或經過constant_score過濾: GET website/_search { "query": { "constant_score": { "filter": { "term": { "author_id": 5520 // 此時全部符合條件的_score都爲1 } } } } }
(2) 定製排序規則:
GET website/_search { "query": { "constant_score": { "filter": { "term": { "author_id": 5520 } } } }, "sort": [ { "post_date": { "order": "asc" } } ] }
版權聲明
出處: 博客園 馬瘦風的博客(https://www.cnblogs.com/shoufeng)
感謝閱讀, 若是文章有幫助或啓發到你, 點個[好文要頂👆] 或 [推薦👍] 吧😜
本文版權歸博主全部, 歡迎轉載, 但 [必須在文章頁面明顯位置標明原文連接], 不然博主保留追究相關人員法律責任的權利.