1. 概述
作为许多开发者首选的搜索引擎之一,Elasticsearch 提供了强大的查询能力。其中一项关键功能是在 filter context 中编写 OR 条件。
在本教程中,我们将逐步讲解如何编写 OR 条件。首先了解什么是 filter context,它与 query context 的区别。然后我们将深入讲解 OR 条件本身,并学习如何在 Elasticsearch 查询中高效实现它。过程中我们还将介绍一些高级技巧。
2. Elasticsearch 中的 Filter Context
在 Elasticsearch 中,filter context 本质上是在回答“是”或“否”的问题。这个文档是否符合给定的条件?与 query context 不同,query context 会根据相关性对结果进行排序,而 filter context 仅仅根据设定的条件包含或排除文档。
举个例子:假设我们正在为一个电商网站构建商品搜索功能。我们可以使用 query context 来查找匹配用户搜索词的商品,并根据匹配程度进行排序。但如果我们想根据价格区间或库存状态来筛选这些商品,就可以使用 filter context。
来看一个示例:
GET /products/_search
{
"query": {
"bool": {
"must": [
{ "match": { "name": "laptop" } }
],
"filter": [
{ "range": { "price": { "lte": 1000 } } },
{ "term": { "in_stock": true } }
]
}
}
}
在这个查询中,**match
部分属于 query context,而 filter
部分属于 filter context**。filter 部分的含义是:“只显示价格在 $1000 以内且有库存的笔记本电脑”。
query context 与 filter context 的主要区别在于评分机制。query context 会计算每个文档的相关性得分,而 filter context 不会。这使得 filter context 在处理简单的“是/否”判断时更快更高效。
另一个关键区别是缓存机制。Elasticsearch 可以缓存 filter 的结果,因此重复使用相同的 filter 会更快。而 query context 则不具备这种缓存优势。
那么什么时候该用哪种 context?
✅ 当我们需要根据相关性对结果排序时,比如文本搜索,使用 query context。
✅ 当我们处理精确值或范围查询时,比如按分类或价格筛选商品,使用 filter context。
3. Elasticsearch 中的 OR 条件
在我们了解了 filter context 的基础之后,现在来聚焦 OR 条件。这个结构允许我们创建基于多个条件的 filter,只要满足其中一个条件即可被包含在结果中。
3.1. OR 操作的基本概念
本质上,Elasticsearch 中的 OR 是一种包容性的操作。它的意思是:“给我满足这个条件,或那个条件,或者两个都满足的文档”。这与 AND 操作相反,AND 要求所有条件都必须满足,因此会限制结果。
在 Elasticsearch 的查询 DSL 中,我们并不会直接写 OR 关键字。而是通过一些结构来隐式地实现 OR 逻辑。最常见的方法是使用 terms
查询,以及在 bool
查询中使用 should
子句。
来看一个示例:
GET /products/_search
{
"query": {
"bool": {
"filter": [
{
"terms": {
"color": ["red", "blue"]
}
}
]
}
}
}
这个查询返回所有颜色是 red 或 blue 的商品。这是一种简单但非常有效的方式来扩展我们想要使用的搜索条件。
3.2. 为什么要在 Filter Context 中使用 OR?
在 filter context 中使用 OR 条件有几个优势,可以让 Elasticsearch 查询更加灵活和高效。
✅ 它能构建更复杂、更精细的过滤器。例如我们可以查找“正在促销 OR 有高评分”的商品。
✅ 相比 query context,OR 条件在 filter context 中性能更好。因为 filter context 不涉及评分计算,Elasticsearch 可以更高效地优化这类操作,而且 filter 的结果通常会被缓存,使得后续使用相同 filter 的查询更快。
✅ 可以简化应用层逻辑。不需要在应用代码中多次查询并合并结果,而是让 Elasticsearch 一次性完成复杂逻辑,从而写出更简洁、易维护的代码。
4. 在 Filter Context 中编写 OR 条件
了解了 OR 条件的概念和优势之后,我们来看看如何在 Elasticsearch 中实现它。有几种方式可以在 filter context 中实现 OR 逻辑,每种都有其适用场景。
4.1. 使用 bool
查询
bool
查询是 Elasticsearch 中最常用的一种查询方式,可以组合多个查询子句,使用布尔逻辑。虽然它常用于 AND 逻辑(通过 must
子句),但在构建 OR 条件时也非常关键。
来看 bool
查询的基本结构:
{
"bool": {
"must": [ ... ],
"filter": [ ... ],
"should": [ ... ],
"must_not": [ ... ]
}
}
在本文中,我们重点关注 filter
和 should
子句。
4.2. 使用 should
子句
在 bool
查询中,should
子句用于实现 OR 逻辑。当它被放在 filter
上下文中时,多个 should
条件之间就形成了 OR 的关系。
看一个例子:
GET /products/_search
{
"query": {
"bool": {
"filter": [
{
"bool": {
"should": [
{ "term": { "color": "red" } },
{ "term": { "size": "large" } }
]
}
}
]
}
}
}
这个查询返回颜色为 red 或尺寸为 large(或两者都满足)的商品。外层 bool
查询的 filter
子句让我们处于 filter context,而内层 bool
查询的 should
子句则构建了 OR 逻辑。
4.3. 组合多个条件
OR 条件中并不限于两个子句,我们可以根据需要添加任意多个 should
条件:
GET /products/_search
{
"query": {
"bool": {
"filter": [
{
"bool": {
"should": [
{ "term": { "color": "red" } },
{ "term": { "size": "large" } },
{ "range": { "price": { "lte": 19.99 } } },
{ "term": { "brand": "acme" } }
]
}
}
]
}
}
}
这个查询返回满足以下任一条件的商品:
- 颜色是 red
- 尺寸是 large
- 价格低于 $19.99
- 品牌是 acme
只要满足其中一个条件,商品就会被包含在结果中。⚠️ 如果商品满足多个条件,它仍然会被包含,但由于是在 filter context 中,不会因为匹配多个条件而提升相关性得分。
5. Filter Context 中的高级 OR 技巧
掌握了基本用法后,我们可以使用更高级的技巧来构建更复杂的查询,应对更复杂的过滤需求。
5.1. 嵌套 OR 条件
有时候我们需要在 OR 条件中再嵌套 OR 条件。这可以通过嵌套 bool
查询来实现:
GET /employees/_search
{
"query": {
"bool": {
"filter": [
{
"bool": {
"should": [
{
"bool": {
"must": [
{ "term": { "department": "sales" } },
{ "range": { "years_experience": { "gte": 5 } } }
]
}
},
{
"bool": {
"must": [
{ "term": { "department": "engineering" } },
{ "term": { "skills": "python" } }
]
}
}
]
}
}
]
}
}
}
这个查询返回满足以下任一条件的员工:
- 属于 sales 部门,且拥有 5 年以上工作经验
- 属于 engineering 部门,且具备 Python 技能
只要满足其中一组条件即可被包含在结果中。
5.2. 混合使用 AND 和 OR 逻辑
通过 bool
查询,我们可以轻松地将 AND 和 OR 逻辑结合在一起,构建更复杂的过滤逻辑:
GET /products/_search
{
"query": {
"bool": {
"filter": [
{ "term": { "category": "electronics" } },
{
"bool": {
"should": [
{ "term": { "brand": "apple" } },
{
"bool": {
"must": [
{ "term": { "brand": "samsung" } },
{ "range": { "price": { "lte": 1000 } } }
]
}
}
]
}
}
]
}
}
}
该查询返回以下商品:
- 属于 electronics 类别
- 是 Apple 品牌,或者
- 是 Samsung 品牌且价格不超过 $1000
这是非常典型的“AND + OR”组合逻辑,可以满足复杂的业务需求。
5.3. 使用 minimum_should_match
参数
当我们有多个 should
条件时,有时希望至少满足其中几个条件。这时可以使用 minimum_should_match
参数来控制:
GET /products/_search
{
"query": {
"bool": {
"must": {
"bool": {
"should": [
{ "term": { "color": "red" } },
{ "term": { "size": "large" } },
{ "range": { "rating": { "gte": 4 } } }
],
"minimum_should_match": 2
}
}
}
}
}
该查询返回的产品必须满足以下三个条件中的至少两个:
- 颜色是 red
- 尺寸是 large
- 评分 ≥ 4
这个参数非常适用于“多选一但至少满足 X 个”的场景。
6. 总结
在本文中,我们深入探讨了如何在 Elasticsearch 的 filter context 中编写 OR 条件。
我们首先理解了 query context 与 filter context 的核心区别。接着,我们学习了如何通过 terms
查询和 bool
查询中的 should
子句来实现 OR 逻辑。最后,我们还介绍了 minimum_should_match
参数,它允许我们控制必须满足的最小条件数。
掌握这些技巧后,你就可以更灵活地构建 Elasticsearch 查询,满足更复杂的业务需求。