bool:布尔组合
是 ES 里的逻辑组合查询 ,用来把多个查询条件 拼在一起,实现 且 / 或 / 非 / 过滤 逻辑。是 ES 官方设计用来组合多个查询条件的核心语法。
| 关键字 | 说明 | 备注 |
|---|---|---|
must |
必须包含,类同 MySQL 关键字AND,计算分值 |
|
should |
可选包含,类同 MySQL 关键字OR |
|
filter |
必须包含,类同 MySQL 关键字AND,不计算分值 |
|
must_not |
不包含,类同 MySQL 不等于关键字 | |
| mixed 水平组合 | 混合以上,类同 MySQL 多个条件平级组合 | |
| mixed 嵌套组合 | 混合以上,类同 MySQL 多个括号组合条件 |
must用法展示
#获取Dest中包含词语 Warsaw,并且dayOfWeek是0的信息
#为了方便观察,这里source中只是展示了一下查询的关键字段
GET index_test/_search
{
"_source": ["Dest","dayOfWeek"],
"query": {
"bool":{
"must": [
{
"match": {
"Dest": "Warsaw"
}
},
{
"term": {
"dayOfWeek": 0
}
}
]
}
}
}
should用法展示:
GET index_test/_search
{
"_source": ["Dest","dayOfWeek"],
"query": {
"bool": {
"should": [
{
"match": {
"Dest": "Warsaw"
}
},
{
"term": {
"dayOfWeek": {
"value": "0"
}
}
}
]
}
},
"sort": [
{
"_score": {
"order": "asc"
}
}
]
}
filter使用案例
GET index_test/_search
{
"_source": ["Dest","dayOfWeek"],
"query": {
"bool":{
"filter": [
{
"match": {
"Dest": "Warsaw"
}
},
{
"term": {
"dayOfWeek": 0
}
}
]
}
}
}
水平多条件查询案例展示:
需要注意的是多个条件之间的顺序安排在es中是没有任何的差异的
GET index_test/_search
{
"_source": ["Dest","dayOfWeek"],
"query": {
"bool":{
"must": [
{
"match": {
"Dest": "Sydney"
}
}
],
"must_not": [
{
"match": {
"Dest": "Warsaw"
}
},
{
"term": {
"dayOfWeek": 0
}
}
]
}
}
}
嵌套形式的多条件查询案例:
首先是查询目的地是Sydney城市的数据,在这些数据中查找天气不是Rain的这个就是嵌套的形式。
GET index_test/_search
{
"_source": ["Dest","dayOfWeek","DestWeather"],
"query": {
"bool":{
"must": [
{
"match": {
"Dest": "Sydney"
}
},
{
"bool": {
"must_not": [
{
"match": {
"DestWeather": "Rain"
}
}
]
}
}
]
}
}
}
Boost加权组合查询:
boosting 是一种分数控制查询 ,用于保留匹配结果但降低部分文档权重,不删除数据,仅对分数打折。
使用boosting
"boosting": {
"positive": 匹配该条件的文档 → 正常打分
"negative": 同时匹配的文档 → 分数被降低
"negative_boost": 0~1 之间的折扣系数
}
- 只匹配 positive 分数 = 原始得分(不改变)
- 同时匹配 positive + negative 分数 = 原始得分 ×
negative_boost(折扣降权) - 只匹配 negative 不返回,直接排除
特点:
- 不删除数据,只降低排名
negative_boost必须 0~1- 以
positive为查询基础 - 与
must_not区别:must_not直接剔除,boosting保留并降权
案例展示
GET index_test/_search
{
"query": {
"boosting": {
"positive": {
"match": {
"Dest": "Chopin"
}
},
"negative": {
"match": {
"DestWeather": "Rain"
}
},
"negative_boost": 0.4
}
}
}
创建mapping时指定权重:
PUT index_test
{
"mappings": {
"properties": {
"name":{
"type": "text",
"boost": 2
}
}
}
}
查询的时候指定boost:
GET index_test/_search
{
"_source": ["Dest","dayOfWeek","DestWeather"],
"query": {
"bool":{
"must": [
{
"match": {
"Dest": {
"query": "Warsaw",
"boost": 5
}
}
},
{
"bool": {
"must_not": [
{
"match": {
"DestWeather": "Rain"
}
}
]
}
}
]
}
}
}
Constant固定分值组合
constant_score :用 filter 过滤数据,所有命中文档给完全一样的固定分数,不做 TF-IDF 相关性计算。
GET index_test/_search
{
"query": {
"constant_score": {
"filter": {
"match":{
"Dest":"Chopin"
}
},
"boost": 1.2
}
}
}
dis_max 最佳匹配查询
全称:Disjunction Max Query(分离最大化查询) 作用:在多个 OR 查询条件中,只取【最佳匹配的那个分数】作为最终得分,不做分数叠加
"dis_max": {
"tie_breaker": 0.7, // 其他匹配条件的加分系数
"boost": 1.2, // 整体查询加权
"queries": [] // 放多个 OR 查询条件
}
1. queries
- 放多个查询条件(match、term、bool 等)
- 条件之间是 OR 关系
- 命中任意一个即可返回
2. tie_breaker(0 ~ 1)
- 只取最高分作为基础分
- 其他命中的条件分数 × tie_breaker 再累加
- 不写 = 0(其他条件完全不加分)
3. boost
-
对整个 dis_max 查询做整体加权
-
最终得分 × boost
GET index_test/_search
{
"query": {
"dis_max": {
"tie_breaker": 0.1,
"boost": 1.2,
"queries": [
{
"term": {
"dayOfWeek": {
"value": 1
}
}
},
{
"match": {
"Dest": {
"query": "Warsaw",
"boost": 5
}
}
}
]
}
}
}
Function函数组合:
function_score:先通过主 query 检索文档,再用 functions 函数二次动态修改评分、控制排序,是 ES 最强自定义打分方案。
| 函数名称 | 作用 | 核心内部参数 | 适用场景 |
|---|---|---|---|
| weight | 固定权重(直接乘分数) | weight |
固定加权、标签加权 |
| random_score | 随机打分 | seed、field |
随机推荐、随机排序 |
| field_value_factor | 用数字字段算分 | field、factor、modifier |
销量 / 热度 / 评分加权 |
| gauss | 高斯衰减(平滑曲线) | origin、scale、offset、decay |
距离、时间、价格最优 |
| linear | 线性衰减 | 同上 | 简单线性衰减 |
| exp | 指数衰减 | 同上 | 快速下降衰减 |
| script_score | 自定义脚本算分 | script |
复杂业务算分 |
| boost_factor | 条件满足后固定加权 | value |
满足某条件直接加权 |
GET index_test/_search
{
"query": {
"function_score": {
"query": {
"bool": {
"must": [
{
"match": {
"Dest": "Warsaw"
}
}
]
}
},
"functions": [
{
"weight": 1,
"filter": {
"term": {
"dayOfWeek": 0
}
}
}
],
"max_boost": 10,
"score_mode": "multiply",
"boost_mode": "multiply",
"min_score": 5
}
}
}
注:这里是一个很大的知识点,,大家可以先了解一下,在开发中遇到的时候在学习一下.对于自定义评分有要求的同学可以自己学习一下这个大佬的视频:使用 Function Score 和 Painless 脚本自定义 Elasticsearch 的评分_哔哩哔哩_bilibili
官网地址:Function score query | Elasticsearch Guide [8.18] | Elastic
这里其实主要掌握bool组合查询就可以了.
script_score
这个是最灵活的方式了
"query": { "function_score": { // ✅ 必须有这个父节点 "query": { "match": { "Dest": "Warsaw" } }, "functions": [ { "script_score": { // ✅ 只能写在这里 "script": { "source": "doc['dayOfWeek'].value" } } } ] } }
范围查询:
GET index_test/_search
{
"query": {
"range": {
"FIELD": {
"gte": 10,
"lte": 20
}
}
}
}
只有存区间类型(range 类型), 才需要用 relation!,下面展示了relation的几个值的含义
| 值 | 含义 | 说明 |
|---|---|---|
within |
文档范围 完全包含在 查询范围内 | 文档区间在查询区间里面 |
contains |
查询范围 完全包含 文档范围 | 查询区间包住文档区间 |
intersects |
范围 有交集即可(默认值) | 重叠一点就算匹配 |
区间类型(range 类型)使用案例:
大家结合案例,自己尝试一下
PUT test
{
"mappings": {
"properties": {
"name":{
"type": "integer_range"
}
}
}
}
GET test/_mapping
PUT test/_doc/1
{
"name":{
"gte": 100,
"lte": 300
}
}
GET test/_search
{
"query": {
"range": {
"name": {
"gte": 150,
"lte": 250,
"relation": "intersects"
}
}
}
}
range字段类型
| 字段类型 | 存储范围类型 | 适用场景 |
|---|---|---|
integer_range |
整型区间 | 年龄、数量、整数区间 |
long_range |
长整型区间 | 大数值 ID、超大整数范围 |
float_range |
单精度浮点区间 | 单价、小数价格 |
double_range |
双精度浮点区间 | 高精度金额、计量数据 |
date_range |
日期时间区间 | 有效期、活动时段、时间跨度 |
ip_range |
IP 地址区间 | IP 段白名单、网段管控 |