Elasticsearch复合查询 #
一、bool查询 #
1.1 bool查询结构 #
json
{
"query": {
"bool": {
"must": [],
"should": [],
"must_not": [],
"filter": []
}
}
}
1.2 子句类型 #
| 子句 | 说明 | 计分 |
|---|---|---|
| must | 必须匹配 | 是 |
| must_not | 必须不匹配 | 否 |
| should | 应该匹配 | 是 |
| filter | 必须匹配 | 否 |
1.3 must子句 #
bash
GET /products/_search
{
"query": {
"bool": {
"must": [
{ "match": { "name": "iPhone" } },
{ "range": { "price": { "lte": 1000 } } }
]
}
}
}
特点:
- 所有条件必须满足
- 参与相关性得分计算
1.4 must_not子句 #
bash
GET /products/_search
{
"query": {
"bool": {
"must": [
{ "match": { "name": "phone" } }
],
"must_not": [
{ "term": { "brand": "Unknown" } },
{ "term": { "status": "deleted" } }
]
}
}
}
特点:
- 条件必须不满足
- 不参与得分计算
- 结果会被缓存
1.5 should子句 #
bash
GET /products/_search
{
"query": {
"bool": {
"should": [
{ "term": { "brand": "Apple" } },
{ "term": { "brand": "Samsung" } }
],
"minimum_should_match": 1
}
}
}
minimum_should_match规则:
| 情况 | 默认值 |
|---|---|
| 只有should | 1 |
| 有must或filter | 0 |
| 手动指定 | 指定值 |
1.6 filter子句 #
bash
GET /products/_search
{
"query": {
"bool": {
"must": [
{ "match": { "name": "iPhone" } }
],
"filter": [
{ "term": { "brand": "Apple" } },
{ "range": { "price": { "gte": 500, "lte": 1500 } } }
]
}
}
}
特点:
- 条件必须满足
- 不参与得分计算
- 结果会被缓存
- 性能更好
1.7 组合使用 #
bash
GET /products/_search
{
"query": {
"bool": {
"must": [
{ "match": { "name": "phone" } }
],
"must_not": [
{ "term": { "status": "deleted" } }
],
"should": [
{ "term": { "brand": "Apple" } },
{ "term": { "brand": "Samsung" } }
],
"filter": [
{ "range": { "price": { "lte": 1000 } } }
],
"minimum_should_match": 1
}
}
}
二、嵌套bool查询 #
2.1 嵌套结构 #
bash
GET /products/_search
{
"query": {
"bool": {
"must": [
{ "match": { "name": "phone" } },
{
"bool": {
"should": [
{ "term": { "brand": "Apple" } },
{ "term": { "brand": "Samsung" } }
]
}
}
]
}
}
}
2.2 复杂嵌套示例 #
bash
GET /products/_search
{
"query": {
"bool": {
"must": [
{ "match": { "name": "phone" } }
],
"should": [
{
"bool": {
"must": [
{ "term": { "brand": "Apple" } },
{ "range": { "price": { "lte": 1000 } } }
]
}
},
{
"bool": {
"must": [
{ "term": { "brand": "Samsung" } },
{ "range": { "price": { "lte": 800 } } }
]
}
}
]
}
}
}
三、boosting查询 #
3.1 基本用法 #
bash
GET /products/_search
{
"query": {
"boosting": {
"positive": {
"match": { "name": "iPhone" }
},
"negative": {
"term": { "status": "refurbished" }
},
"negative_boost": 0.5
}
}
}
说明:
- positive:正常匹配的文档
- negative:需要降低权重的文档
- negative_boost:降低系数(0-1)
3.2 得分计算 #
text
最终得分 = positive得分 × (negative匹配 ? negative_boost : 1)
3.3 应用场景 #
text
应用场景
├── 降低过时内容权重
├── 降低低质量内容权重
├── 降低特定状态文档权重
└── 保留文档但降低排名
四、constant_score查询 #
4.1 基本用法 #
bash
GET /products/_search
{
"query": {
"constant_score": {
"filter": {
"term": { "brand": "Apple" }
},
"boost": 1.2
}
}
}
4.2 特点 #
- 所有匹配文档得分相同
- 不计算相关性得分
- 性能更好
4.3 应用场景 #
text
应用场景
├── 精确过滤场景
├── 不需要相关性排序
├── 作为bool的filter子句
└── 自定义得分场景
五、dis_max查询 #
5.1 基本用法 #
bash
GET /products/_search
{
"query": {
"dis_max": {
"queries": [
{ "match": { "name": "iPhone" } },
{ "match": { "description": "iPhone" } }
],
"tie_breaker": 0.3
}
}
}
5.2 得分计算 #
text
无tie_breaker: 最高分
有tie_breaker: 最高分 + tie_breaker × 其他得分之和
5.3 与bool的区别 #
| 查询 | 得分计算 |
|---|---|
| bool | 所有子句得分求和 |
| dis_max | 取最高分 |
5.4 应用场景 #
text
应用场景
├── 多字段搜索
├── 最佳匹配优先
└── 避免得分叠加
六、function_score查询 #
6.1 基本用法 #
bash
GET /products/_search
{
"query": {
"function_score": {
"query": {
"match": { "name": "iPhone" }
},
"boost": 1.0,
"functions": [
{
"filter": { "term": { "featured": true } },
"weight": 2
},
{
"field_value_factor": {
"field": "rating",
"factor": 1.2,
"modifier": "sqrt"
}
}
],
"score_mode": "sum",
"boost_mode": "multiply"
}
}
}
6.2 函数类型 #
| 函数 | 说明 |
|---|---|
| weight | 固定权重 |
| field_value_factor | 字段值影响得分 |
| script_score | 脚本计算得分 |
| random_score | 随机得分 |
| decay functions | 衰减函数 |
6.3 field_value_factor #
bash
{
"field_value_factor": {
"field": "popularity",
"factor": 1.2,
"modifier": "sqrt",
"missing": 1
}
}
modifier选项:
| 值 | 公式 |
|---|---|
| none | factor × field |
| log | log(factor × field) |
| log1p | log(1 + factor × field) |
| log2p | log(2 + factor × field) |
| ln | ln(factor × field) |
| ln1p | ln(1 + factor × field) |
| ln2p | ln(2 + factor × field) |
| sqrt | sqrt(factor × field) |
| square | (factor × field)² |
| reciprocal | 1 / (factor × field) |
6.4 script_score #
bash
{
"script_score": {
"script": {
"source": "Math.log(2 + doc['popularity'].value)"
}
}
}
6.5 random_score #
bash
{
"random_score": {
"seed": 12345,
"field": "_seq_no"
}
}
6.6 decay functions #
bash
{
"gauss": {
"price": {
"origin": 500,
"scale": 100,
"decay": 0.5
}
}
}
衰减函数类型:
| 函数 | 形状 |
|---|---|
| linear | 线性衰减 |
| gauss | 高斯衰减 |
| exp | 指数衰减 |
6.7 score_mode #
| 值 | 说明 |
|---|---|
| multiply | 函数得分相乘(默认) |
| sum | 函数得分相加 |
| avg | 函数得分平均 |
| first | 使用第一个函数得分 |
| max | 使用最大函数得分 |
| min | 使用最小函数得分 |
6.8 boost_mode #
| 值 | 说明 |
|---|---|
| multiply | 查询得分 × 函数得分(默认) |
| replace | 使用函数得分 |
| sum | 查询得分 + 函数得分 |
| avg | 查询得分与函数得分平均 |
| max | 取最大值 |
| min | 取最小值 |
七、查询命名 #
7.1 命名查询 #
bash
GET /products/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"name": {
"query": "iPhone",
"_name": "name_filter"
}
}
}
],
"filter": [
{
"term": {
"brand": {
"value": "Apple",
"_name": "brand_filter"
}
}
}
]
}
}
}
7.2 响应中的命名 #
json
{
"hits": {
"hits": [
{
"_index": "products",
"_id": "1",
"matched_queries": ["name_filter", "brand_filter"]
}
]
}
}
八、查询权重 #
8.1 boost参数 #
bash
GET /products/_search
{
"query": {
"bool": {
"should": [
{ "match": { "name": { "query": "iPhone", "boost": 3 } } },
{ "match": { "description": { "query": "iPhone", "boost": 1 } } }
]
}
}
}
8.2 权重建议 #
text
权重建议
├── 标题字段
│ └── boost: 3-5
├── 描述字段
│ └── boost: 1-2
├── 标签字段
│ └── boost: 2-3
└── 内容字段
└── boost: 1
九、最佳实践 #
9.1 查询优化 #
text
优化建议
├── 使用filter代替must
│ └── 不需要得分时
├── 合理使用should
│ └── 配合minimum_should_match
├── 避免过度嵌套
│ └── 简化查询结构
└── 使用命名查询
└── 便于调试
9.2 性能考虑 #
text
性能优化
├── filter优先
│ └── 利用缓存
├── 减少子句数量
│ └── 简化查询
├── 避免脚本
│ └── 性能影响大
└── 合理分页
└── 避免深度分页
十、总结 #
本章介绍了Elasticsearch复合查询:
- bool查询是最常用的复合查询
- must/should/must_not/filter各有用途
- boosting查询用于降低特定文档权重
- constant_score用于固定得分
- function_score实现自定义得分
- 合理使用权重优化搜索结果
下一步,我们将学习全文搜索。
最后更新:2026-03-27