bool(組合查詢)
- must 所有的語句都 必須(must) 匹配,與 AND 、= 等價。
- must_not 所有的語句都 不能(must not) 匹配,與 NOT 、!= 等價。
- should 至少有一個語句要匹配,與 OR 等價。
filter | 只過濾符合條件的文檔,不計算相關系得分 |
must | 文檔必須符合must中所有的條件,會影響相關性得分 |
must_not | 文檔必須不符合must_not 中的所有條件 |
should | 文檔可以符合should中的條件 |
它類似於SQL中的WHERE A = 'a' AND B = 'c' OR C = 'c'
。一個 bool 過濾器由三部分組成:
{ "bool" : { "must" : [], "should" : [], "must_not" : [], } }
布爾查詢是一種最常用的組合查詢方式,布爾查詢把多個子查詢組合(combine)成一個布爾表達式,所有子查詢之間的邏輯關系是與(and);只有當一個文檔滿足布爾查詢中的所有子查詢條件時,ElasticSearch引擎才認為該文檔滿足查詢條件。布爾查詢支持的子查詢類型共有四種,分別是:must,should,must_not和filter:
查詢字句 | 說明 | 類型 |
---|---|---|
must | 文檔必須匹配must查詢條件 | 數組 |
should | 文檔應該匹配should子句查詢的一個或多個 | 數組 |
must_not | 文檔不能匹配該查詢條件 | 數組 |
filter | 過濾器,文檔必須匹配該過濾條件,跟must子句的唯一區別是,filter不影響查詢的score | 字典 |
filter查詢
- filter查詢只過濾符合條件的文檔,es會有只能緩存,因此其執行效率很高,做簡單的匹配查詢且不考慮算分是,推薦使用filter替代query
上下文類型 | 執行類型 | 使用方式 |
---|---|---|
Query | 查找和查詢語句最匹配的文檔,對所有文檔進行相關性算分排序 | query查詢 bool中的must和should |
Filter | 查找和查詢語句匹配的文檔 | bool中的filter和must_not或者constant_score中的filter |
should查詢
使用分兩種情況
bool查詢包含should,不包含must查詢,只包含should,文檔必須滿足至少一個條件,minimum_should_match可以滿足條件的個數或者百分比。
bool查詢同時包含should和must查詢,文檔不必滿足should中的條件,但是如果滿足條件,會增加相關性得分(dis_max query/function_score query
/boosting query)。
filter執行原理深度剖析
1.在倒排索引中查找搜索串,獲取document list。
2.為每個在倒排索引中搜索到的結果,構建一個bitset,[0, 0, 0, 1, 0, 1]
3.遍歷每個過濾條件對應的bitset,優先從最稀疏的開始搜索,查找滿足所有條件的document
4.caching bitset,跟蹤query,在最近256個query中超過一定次數的過濾條件,緩存其bitset。對於小segment(<1000,或<3%),不緩存bitset。
5.filter大部分情況下來說,在query之前執行,先盡量過濾掉盡可能多的數據
6.如果document有新增或修改,那么cached bitset會被自動更新
7.以后只要是有相同的filter條件的,會直接來使用這個過濾條件對應的cached bitset
sql:
select * from paper where (date="2018-10-11" or uID= 1) and pID!="7ec0e0e5-a4b0-46d7-af56-5b3eab477aea" es: GET blog/paper/_search { "query": { "bool": { "should": [ {"term": {"date":"2018-10-11"}}, {"term": {"uID":1}} ] , "must_not": [ {"term": {"pID": "7ec0e0e5-a4b0-46d7-af56-5b3eab477aea"}} ] } } }
2.並且或者查詢
select *from paper where date= "2018-10-11" or(uid=1 and publish= 1) GET blog/paper/_search { "query": { "bool": { "should": [ {"term": {"date": "2018-10-11"}}, {"bool": { "must": [ {"term": {"uID": "1"}}, {"term": {"publish": true}} ] }} ] } } }
3.搜索java,elasticsearch,hadoop,spark關鍵字需要至少匹配2個
GET blog/paper/_search { "query": { "bool": { "should": [ {"match": { "title": "java" }}, {"match": { "title": "elasticsearch" }}, {"match": { "title": "hadoop" }}, {"match": { "title": "spark" }} ] , "minimum_should_match": 2 } } }
range(范圍查詢)
我們可以用它來查找處於某個范圍內的文檔。比如我們在商品中查找價格大於 $20 且小於 $40 美元的。
GET /index/type/_search { "query": { "range": { "price": { "gte": 20, "lte": 40 } } } }
range
查詢可同時提供包含(inclusive)和不包含(exclusive)這兩種范圍表達式,可供組合的選項如下:
- gt: > 大於(greater than)
- lt: < 小於(less than)
- gte: >= 大於或等於(greater than or equal to)
- lte: <= 小於或等於(less than or equal to)。
range 還可以支持日期范圍
, 字符串范圍
類型,特別是在進行日期范圍查詢時,range還可以支持日期計算。
像這樣:
"range" : { "timestamp" : { "gt" : "now-1h" } } OR "range" : { "timestamp" : { "gt" : "2014-01-01", "lt" : "2014-01-01||+1y" } }