0%

elasticsearch复杂查询

Elasticsearch 复杂查询详解:复合查询与逻辑组合

在 Elasticsearch 中,复杂查询通过组合多个简单查询条件,实现精准的数据过滤和相关性排序。核心复合查询包括 bool(布尔逻辑)、dis_max(取最大值)和 boosting(评分调整)等,适用于多条件组合、多字段匹配等场景。

bool 查询:布尔逻辑组合

bool 查询是最常用的复合查询,通过 mustfiltershouldmust_not 四个子句组合多个查询条件,实现类似 ANDORNOT 的逻辑关系。

核心子句说明

子句 作用 是否影响评分 类比逻辑
must 必须匹配的条件(所有条件都满足) AND
filter 必须匹配的条件(与 must 功能相同,但不参与评分) AND
should 可选匹配的条件(至少满足一个,除非有 must/filter 子句) OR
must_not 必须不匹配的条件(排除符合条件的文档) NOT

配置参数

  • minimum_should_match:指定 should 子句中至少需要匹配的条件数量(默认:当存在 must/filter 时为 0,否则为 1)。
  • boost:为整个 bool 查询设置权重(默认 1.0)。

示例:多条件组合查询

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
GET products/_search
{
"query": {
"bool": {
"must": [ // 必须满足的条件(影响评分)
{ "match": { "name": "手机" } }, // 名称包含“手机”
{ "range": { "price": { "gte": 1000 } } } // 价格≥1000
],
"filter": [ // 必须满足的条件(不影响评分,可缓存)
{ "term": { "brand.keyword": "华为" } }, // 品牌是华为(精确匹配)
{ "range": { "stock": { "gt": 0 } } } // 库存>0
],
"should": [ // 可选条件(满足得高分)
{ "term": { "tags.keyword": "新品" } }, // 标签包含“新品”
{ "term": { "tags.keyword": "促销" } } // 标签包含“促销”
],
"must_not": [ // 必须不满足的条件
{ "term": { "type.keyword": "二手" } } // 排除二手商品
],
"minimum_should_match": 1 // 至少满足1个should条件
}
}
}

关键特性

  • filter 子句的结果会被缓存,适合频繁执行的过滤条件(如状态、时间范围),性能优于 must
  • 支持嵌套 bool 查询(如在 should 中嵌套另一个 bool),实现复杂逻辑。

dis_max 查询:取多个查询的最高分

dis_max(Disjunction Max)查询用于执行多个子查询,取其中得分最高的作为文档的最终得分,适合多字段匹配但希望突出最佳匹配的场景(如搜索标题和内容,以匹配度最高的字段为准)。

核心参数

  • queries:待执行的子查询列表(数组形式)。
  • tie_breaker:打破平局的因子(0~1 之间),用于将其他子查询的得分按比例叠加到最高分上(默认 0.0,即只取最高分)。
  • boost:为整个查询设置权重(默认 1.0)。

示例:多字段最佳匹配

1
2
3
4
5
6
7
8
9
10
11
12
GET articles/_search
{
"query": {
"dis_max": {
"tie_breaker": 0.3, // 其他子查询得分的30%叠加到最高分
"queries": [
{ "match": { "title": "elasticsearch 教程" } }, // 标题查询
{ "match": { "content": "elasticsearch 教程" } } // 内容查询
]
}
}
}
得分计算逻辑:

假设标题匹配得分为 1.5,内容匹配得分为 0.8,则最终得分为:
1.5 + (0.8 × 0.3) = 1.74

适用场景

  • 多字段搜索(如标题、摘要、正文),希望优先展示在某个字段上高度匹配的文档。
  • 避免因多个字段低匹配度叠加导致的 “伪相关” 结果。

boosting 查询:降级匹配文档的得分

boosting 查询用于 “包含但降级” 某些文档 —— 即保留符合特定条件的文档,但降低其相关性得分,而不是完全排除。

核心参数

  • positive:必须匹配的主查询(得分正常计算)。
  • negative:需要降级的辅助查询(匹配的文档得分会被降低)。
  • negative_boost:降级系数(0~1 之间),匹配 negative 的文档得分会乘以该系数。

示例:保留但降级特定文档

1
2
3
4
5
6
7
8
9
10
GET books/_search
{
"query": {
"boosting": {
"positive": { "match": { "title": "机器学习" } }, // 主查询:标题含“机器学习”
"negative": { "match": { "content": "入门" } }, // 降级条件:内容含“入门”
"negative_boost": 0.5 // 匹配降级条件的文档得分乘以0.5
}
}
}
效果:
  • 所有标题含 “机器学习” 的文档都会被返回。
  • 其中内容含 “入门” 的文档得分会降低(变为原来的 50%),在结果中排序靠后。

适用场景

  • 过滤 “相关但质量较低” 的文档(如搜索 “深度学习” 时,降级包含 “入门”“基础” 的文档)。
  • 需保留所有相关结果,但希望优先展示更符合核心需求的文档。

复合查询的嵌套与组合

复杂业务场景往往需要嵌套多种复合查询,例如在 boolshould 中嵌套 dis_max,或在 filter 中嵌套 bool

示例:嵌套查询

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
GET orders/_search
{
"query": {
"bool": {
"must": [
{ "range": { "amount": { "gte": 1000 } } } // 订单金额≥1000
],
"should": [
// 嵌套dis_max:匹配“VIP用户”或“近30天订单”,取最高分
{
"dis_max": {
"queries": [
{ "term": { "user_level.keyword": "VIP" } },
{ "range": { "create_time": { "gte": "now-30d" } } }
]
}
}
],
"minimum_should_match": 1
}
}
}

欢迎关注我的其它发布渠道

表情 | 预览
快来做第一个评论的人吧~
Powered By Valine
v1.3.10