Elasticsearch(下面簡稱ES)中的bool查詢在業務中使用也是比較多的。在一些非實時的分頁查詢,導出的場景,咱們常常使用bool查詢組合各類查詢條件。緩存
Bool查詢包括四種子句,性能
我這裏只介紹下must和filter兩種子句,由於是咱們今天要講的重點。其它的能夠自行查詢官方文檔。優化
從上面的描述來看,你應該已經知道,若是隻看查詢的結果,must和filter是同樣的。區別是場景不同。若是結果須要算分就使用must,不然能夠考慮使用filter。ui
光說比較抽象,看個例子,下面兩個語句,查詢的結果是同樣的。spa
使用filter過濾時間範圍,3d
GET kibana_sample_data_ecommerce/_search { "size": 1000, "query": { "bool": { "must": [ {"term": { "currency": "EUR" }} ], "filter": { "range": { "order_date": { "gte": "2020-01-25T23:45:36.000+00:00", "lte": "2020-02-01T23:45:36.000+00:00" } } } } } }
使用must過濾時間範圍,code
GET kibana_sample_data_ecommerce/_search { "size": 1000, "query": { "bool": { "must": [ {"term": { "currency": "EUR" }}, {"range": { "order_date": { "gte": "2020-01-25T23:45:36.000+00:00", "lte": "2020-02-01T23:45:36.000+00:00" } }} ] } } }
查詢的結果都是,blog
{ "took" : 25, "timed_out" : false, "_shards" : { "total" : 1, "successful" : 1, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : { "value" : 1087, "relation" : "eq" }, ...
上一節你已經知道了must和filter的基本用法和區別。簡單來說,若是你的業務場景不須要算分,使用filter能夠真的讓你的查詢效率飛起來。索引
爲了說明filter查詢高效的緣由,咱們須要引入ES的一個概念query context
和filter context
。ip
query context
query context
關注的是,文檔到底有多匹配查詢的條件,這個匹配的程度是由相關性分數決定的,分數越高天然就越匹配。因此這種查詢除了關注文檔是否知足查詢條件,還須要額外的計算相關性分數.
filter context
filter context
關注的是,文檔是否匹配查詢條件,結果只有兩個,是和否。沒有其它額外的計算。它經常使用的一個場景就是過濾時間範圍。
而且filter context會自動被ES緩存結果,效率進一步提升。
對於bool查詢,must使用的就是query context
,而filter使用的就是filter context
。
咱們能夠經過一個示例驗證下。繼續使用第一節的例子,咱們經過kibana自帶的search profiler
來看看ES的查詢的詳細過程。
使用must查詢的執行過程是這樣的:
能夠明顯看到,這次查詢計算了相關性分數,並且score的部分佔據了查詢時間的10分之一左右。
filter的查詢我就不截圖了,區別就是score這部分是0,也就是不計算相關性分數。
除了是否計算相關性算分的差異,常常使用的過濾器將被Elasticsearch自動緩存,以提升性能。
我本身曾經在一個項目中,對一個業務查詢場景作了這種優化,當時線上的索引文檔數量大概是3000萬左右,改爲filter以後,查詢的速度幾乎快了一倍。
我截了幾張圖,你來感覺下。
咱們應該根據本身的實際業務場景選擇合適的查詢語句,在某些不須要相關性算分的查詢場景,儘可能使用filter context
可讓你的查詢更加高效。