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复合查询:

  1. bool查询是最常用的复合查询
  2. must/should/must_not/filter各有用途
  3. boosting查询用于降低特定文档权重
  4. constant_score用于固定得分
  5. function_score实现自定义得分
  6. 合理使用权重优化搜索结果

下一步,我们将学习全文搜索。

最后更新:2026-03-27