ES 23 - 檢索和過濾的區別 (query v.s filter)


本文以 ES 6.6.0 版本為例進行演示.

1 filter與query示例

1.1 准備測試數據

PUT website/_doc/1
{
    "title": "小白學ES01",
    "desc": "the first blog about es",
    "level": 1, 
    "post_date": "2018-10-10",
    "post_address": {
        "country": "China",
        "province": "GuangDong",
        "city": "GuangZhou"
    }
}

PUT website/_doc/2
{
    "title": "小白學ES02",
    "desc": "the second blog about es",
    "level": 3,
    "post_date": "2018-11-11",
    "post_address": {
        "country": "China",
        "province": "ZheJiang",
        "city": "HangZhou"
    }
}

1.2 搜索測試

搜索條件: 搜索博客等級(level)大於等於2, 同時發布日期(post_date)是2018-11-11的博客:

(1) 不使用filter:

GET website/_doc/_search
{
    "query": {
        "bool": {
            "must": [
                { "match": { "post_date": "2018-11-11" } }, 
                { "range": { "level": { "gte": 2 } } }
            ]
        }
    }
}
// 結果信息: 
"hits": {
    "total": 1,
    "max_score": 2.0,
    "hits": [
        {
            "_index": "website2",
        	"_type": "blog",
        	"_id": "2",
        	"_score": 2.0,			// 評分為2.0
        	"_source": {
          		"title": "小白學ES02",
          		"desc": "the second blog about es",
          		"level": 3,
          		"post_date": "2018-11-11",
          		"post_address": {
            		"country": "China",
            		"province": "ZheJiang",
            		"city": "HangZhou"
          		}
        	}
      	}
	]
}

(2) 使用filter:

GET website/_doc/_search
{
    "query": {
        "bool": {
            "must": { 
                "match": { "post_date": "2018-11-11" }
            }, 
            "filter": {
                "range": { "level": { "gte": 2 } }
            }
        }
    }
}
// 結果信息: 
"hits": {
    "total": 1,
    "max_score": 1.0,
    "hits": [
        {
        	"_index": "website2",
        	"_type": "blog",
        	"_id": "2",
        	"_score": 1.0,		// 評分為1.0
        	"_source": {
          		"title": "小白學ES02",
          		"desc": "the second blog about es",
          		"level": 3,
          		"post_date": "2018-11-11",
          		"post_address": {
            		"country": "China",
            		"province": "ZheJiang",
            		"city": "HangZhou"
          		}
        	}
      	}
    ]
}

2 filter與query的區別

filter和query一起使用時, 會先執行filter.

2.1 相關度處理上的不同

filter —— 只根據搜索條件過濾出符合的文檔, 將這些文檔的評分固定為1, 忽略TF/IDF信息, 不計算相關度分數;
query —— 先查詢符合搜索條件的文檔, 然后計算每個文檔對於搜索條件的相關度分數, 再根據評分倒序排序.

建議:

  • 如果對搜索結果有排序的要求, 要將最匹配的文檔排在最前面, 就用query;
  • 如果只是根據一定的條件篩選出部分數據, 不關注結果的排序, 就用filter.

2.2 性能上的對比

filter 性能更好, 無排序 —— 不計算相關度分數, 不用根據相關度分數進行排序, 同時ES內部還會緩存(cache)比較常用的filter的數據 (使用bitset <0或1> 來記錄包含與否).

query 性能較差, 有排序 —— 要計算相關度分數, 要根據相關度分數進行排序, 並且沒有cache功能.

2.3 對比結論

  1. 業務關心的、需要根據匹配的相關度進行排序的搜索條件 放在 query 中;

  2. 業務不關心、不需要根據匹配的相關度進行排序的搜索條件 放在 filter 中.

版權聲明

作者: 馬瘦風(https://healchow.com)

出處: 博客園 馬瘦風的博客(https://www.cnblogs.com/shoufeng)

感謝閱讀, 如果文章有幫助或啟發到你, 點個[好文要頂👆] 或 [推薦👍] 吧😜

本文版權歸博主所有, 歡迎轉載, 但 [必須在文章頁面明顯位置標明原文鏈接], 否則博主保留追究相關人員法律責任的權利.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM