1. 程式人生 > >ES 的query 和 filter 區別

ES 的query 和 filter 區別

Elasticsearch支援很多查詢方式,其中一種就是DSL,它是把請求寫在JSON裡面,然後進行相關的查詢。 

Query DSL 與 Filter DSL


DSL查詢語言中存在兩種:查詢DSL(query DSL)和過濾DSL(filter DSL)。

它們兩個的區別如下圖:

image

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:

image

http://xiaorui.cc/2015/11/09/elasticsearch%E7%9A%84%E6%9F%A5%E8%AF%A2%E5%99%A8query%E4%B8%8E%E8%BF%87%E6%BB%A4%E5%99%A8filter%E7%9A%84%E5%8C%BA%E5%88%AB/

  

上面文章提供了一個測試例子。

  • 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" }} 
        } 
    }