在 Elasticsearch 的布爾查詢(bool query
)中,must
和 filter
是兩個核心子句,它們的核心區別在于 是否影響相關性評分,這直接決定了它們在查詢性能、使用場景和結果排序上的差異。以下是詳細對比:
一、核心區別
二、底層原理
1.?must
?子句
-
執行流程:
- 對每個文檔執行查詢條件
- 計算匹配條件的相關性評分(
_score
) - 合并所有?
must
?子句的評分(默認相加) - 按總分排序結果
- 典型應用:
{"query": {"bool": {"must": [{ "match": { "title": "elasticsearch" } }, // 全文搜索{ "range": { "price": { "gte": 100 } } } // 范圍條件(但需要影響排序)]}}
}
2.?filter
?子句
-
執行流程:
- 使用倒排索引快速過濾文檔(無需計算評分)
- 結果集返回匹配文檔(不排序)
- 若與其他評分查詢組合,僅傳遞過濾后的文檔給評分模塊
-
典型應用:
{"query": {"bool": {"must": [ { "match": { "title": "elasticsearch" } } ],"filter": [ { "term": { "status": "published" } }, // 精確匹配{ "range": { "publish_date": { "gte": "2023-01-01" } } }]}}
}
三、使用場景對比
1.?必須使用?must
?的場景
- 需求涉及相關性排序:?例如:搜索商品時,關鍵詞匹配度高的結果需要排在前面。
- 需要組合多個相關性條件:?例如:同時匹配標題和內容的關鍵詞,且兩者的匹配度共同影響排序。
2.?必須使用?filter
?的場景
- 精確篩選數據:?例如:過濾出狀態為“已發布”、價格在 100-500 元之間的商品。
- 高頻重復查詢:?例如:電商平臺首頁的“促銷商品”篩選(同樣條件會被多次執行)。
- 不關心排序的過濾:?例如:審計日志的時間范圍過濾,結果按時間倒序即可。
四、性能優化技巧
1.?層級優化原則
將過濾條件盡量放在 filter
中,優先縮小數據集:
{"query": {"bool": {"must": [ { "match": { "content": "性能優化" } } ],"filter": [{ "term": { "category": "技術文檔" } },{ "range": { "view_count": { "gte": 1000 } } }]}}
}
2.?強制跳過評分
對 must
中的非相關性條件使用 constant_score
:
{"query": {"bool": {"must": [{ "match": { "title": "elasticsearch" } },{ "constant_score": { // 此條件不貢獻評分"filter": { "term": { "version": "7.x" } },"boost": 0 // 評分權重設為0}}]}}
}
3.?緩存驗證
通過 _search
API 的 profile
參數驗證是否命中緩存:
GET /index/_search?request_cache=true
{"query": { "bool": { "filter": [ {...} ] } }
}
五、錯誤使用案例
1.?誤用?must
?導致性能下降
// 錯誤:用 must 處理精確匹配
{"bool": {"must": [{ "term": { "status": "active" } }, // 精確條件應放在 filter{ "range": { "age": { "gte": 18 } } }]}
}
2.?誤用?filter
?導致排序失效
// 錯誤:用 filter 處理需要影響排序的條件
{"bool": {"must": [ { "match": { "title": "緊急通知" } } ],"filter": [ { "range": { "priority": { "gte": 5 } } } ] // priority 應影響排序}
}
六、高級組合用法
1.?混合使用提升性能
{"query": {"bool": {"must": [ { "match": { "text": "error" } } ],"filter": [{ "term": { "service": "gateway" } },{ "range": { "@timestamp": { "gte": "now-1h" } } }]}}
}
2.?嵌套 bool 查詢
{"query": {"bool": {"must": [{ "match": { "title": "系統故障" } },{ "bool": { "filter": [ // 嵌套的過濾條件{ "term": { "environment": "prod" } },{ "range": { "severity": { "gte": 3 } } }]}}]}}
}
七、總結
must
?的本質:貢獻相關性評分的條件,適用于需要影響結果排序的場景。filter
?的本質:高效的二進制過濾器,適用于精確匹配和高頻查詢。- 黃金法則:?能用?
filter
?的不要用?must
?—— 除非明確需要該條件影響評分。