ES 的query 和 filter 區別
Elasticsearch支援很多查詢方式,其中一種就是DSL,它是把請求寫在JSON裡面,然後進行相關的查詢。
Query DSL 與 Filter DSL
DSL查詢語言中存在兩種:查詢DSL(query DSL)和過濾DSL(filter DSL)。
它們兩個的區別如下圖:
query DSL
在查詢上下文中,查詢會回答這個問題——“這個文件匹不匹配這個查詢,它的相關度高麼?”
如何驗證匹配很好理解,如何計算相關度呢?ES中索引的資料都會儲存一個_score分值,分值越高就代表越匹配。另外關於某個搜尋的分值計算還是很複雜的,因此也需要一定的時間。
查詢上下文 是在 使用query進行查詢時的執行環境,比如使用search的時候。
一些query的場景:
- 與full text search的匹配度最高
- 包含run單詞,如果包含這些單詞:runs、running、jog、sprint,也被視為包含run單詞
- 包含quick、brown、fox。這些詞越接近,這份文件的相關性就越高
filter DSL
在過濾器上下文中,查詢會回答這個問題——“這個文件匹不匹配?”
答案很簡單,是或者不是。它不會去計算任何分值,也不會關心返回的排序問題,因此效率會高一點。
過濾上下文 是在使用filter引數時候的執行環境,比如在bool查詢中使用Must_not或者filter
另外,經常使用過濾器,ES會自動的快取過濾器的內容,這對於查詢來說,會提高很多效能。
一些過濾的情況:
- 建立日期是否在2013-2014年間?
- status欄位是否為published?
- lat_lon欄位是否在某個座標的10公里範圍內?
參考: http://www.cnblogs.com/xing901022/p/4975931.html
下圖的查詢就是一個組合查詢, 既有 filter 也有 query:
上面文章提供了一個測試例子。
- query語句查詢結果,第一次查詢用了300ms,第二次用了280ms.
- filter查詢出來的結果,第一次查詢時間是280ms,第二次130ms。
具體如何寫 查詢和 過濾並存的請看下面這篇文章:
查詢與過濾條件的合併
http://es.xiaoleilu.com/054_Query_DSL/75_Queries_with_filters.html
比如說我們有這樣一條查詢語句,獲取右鍵內容中帶“business opportunity
” 的:
{
"match": {
"email": "business opportunity"
}
}
然後我們想要讓這條語句加入 term 過濾,只在收信箱中匹配郵件:
{
"term": {
"folder": "inbox"
}
}
search API中只能包含 query 語句,所以我們需要用 filtered 來同時包含 "query" 和 "filter" 子句:
{
"filtered": {
"query": { "match": { "email": "business opportunity" }},
"filter": { "term": { "folder": "inbox" }}
}
}
我們在外層再加入 query 的上下文關係:
GET /_search
{
"query": {
"filtered": {
"query": { "match": { "email": "business opportunity" }},
"filter": { "term": { "folder": "inbox" }}
}
}
}