文章十八:Elasticsearch 多条件组合查询实战运用

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 之间的折扣系数
}
  1. 只匹配 positive 分数 = 原始得分(不改变
  2. 同时匹配 positive + negative 分数 = 原始得分 × negative_boost折扣降权
  3. 只匹配 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 随机打分 seedfield 随机推荐、随机排序
field_value_factor 用数字字段算分 fieldfactormodifier 销量 / 热度 / 评分加权
gauss 高斯衰减(平滑曲线) originscaleoffsetdecay 距离、时间、价格最优
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 段白名单、网段管控
相关推荐
weixin_307779131 小时前
云计算大数据Azure服务分类详解
大数据·分类·自动化·云计算·azure
jason成都1 小时前
jetlinks社区版本扩展-TDengine
大数据·时序数据库·tdengine
久菜盒子工作室2 小时前
中国工业气体行业研究报告(2026)
大数据·人工智能
财经资讯数据_灵砚智能2 小时前
基于全球经济类多源新闻的NLP情感分析与数据可视化(夜间-次晨)2026年5月1日
大数据·人工智能·python·信息可视化·自然语言处理
爱学习的张大2 小时前
具身智能论文精读(六):pi0
搜索引擎
葫三生2 小时前
三生原理文章被AtomGit‌开源社区收录的意义探析?
人工智能·深度学习·神经网络·算法·搜索引擎·开源·transformer
weixin_446260853 小时前
应用实战篇:利用 DeepSeek V4 构建生产级 AI 应用的全流程与最佳实践
大数据·linux·人工智能
AI木马人3 小时前
13.人工智能实战:RAG 多轮对话越问越偏?Query Rewrite、历史压缩与会话记忆的工程化方案
人工智能·搜索引擎
小王毕业啦13 小时前
2005-2024年 省级-总抚养比、儿童抚养比、老年人抚养比数据(xlsx)
大数据·人工智能·数据挖掘·数据分析·社科数据·实证分析·经管数据