当前位置: 首页 > news >正文

Elasticsearch QueryDSL 教程

什么是 Elasticsearch QueryDSL

Elasticsearch Query DSL 是 Elasticsearch 用来构建和执行搜索查询的 JSON 格式查询语言,支持丰富的查询和过滤条件,帮助用户精准检索和分析数据。它类似于 MySQL 中的 SQL 查询语句(SELECT 语句),都是用来定义从数据库或索引中筛选和返回数据的规则和条件。

MySql 和 Elasticsearch 的区别

MySQL 概念Elasticsearch 概念说明
数据库(Database)索引(Index)ES 中一个 Index 就相当于 MySQL 中的一个数据库,里面存储类结构相似的数据。比如 users 索引存放用户数据,orders 索引存放订单数据。
表(Table)类型(Type,7.x 后已废弃)早期 ES 在一个索引里可以有多种 Type,像数据库里的一张张表。但从 7.x 开始官方废弃 Type,一个 Index 只能有一种数据结构,相当于 一个索引 = 一张表。
行(Row)文档(Document)ES 存储的最小单位是一个 Document,相当于 MySQL 里的一行数据。文档用 JSON 格式存储。
列(Column)字段(Field)Document 里的每个 key/value 就是一个 Field,对应 MySQL 里的列。
主键(Primary Key)_id每个 Document 都有唯一的 _id,相当于主键,可以由 ES 自动生成,也可以手动指定。
SQLQuery DSLMySQL 用 SQL 查询,ES 用 Query DSL(一种 JSON 风格的查询语法)。


数据类型介绍

一. 核心数据类型(Core datatypes)

类型名说明典型用途

text

分词后的字符串,用于全文检索

商品描述、文章内容、评论、日志文本等

keyword

不分词的字符串,适合精确匹配和聚合

标签、状态码、分类、用户名、ID、邮箱等

boolean

布尔值(true / false)

是否启用,开关标识

integer

32位整数

年龄、数量、评分等

long

64位整数

大整数计数、时间戳

short

16位整数

较小范围数值

byte

8位整数

非常小的整数范围

double

双精度浮点数

价格、权重、坐标等

float

单精度浮点数

轻量级浮点数

half_float

半精度浮点数

对精度要求较低的浮点数

scaled_float

以整数存储浮点数,乘以缩放因子存储

金额、价格(避免浮点误差)

date

日期时间类型,支持多种格式

订单时间、日志时间

date_nanos

纳秒精度日期时间

高精度时间戳

二. 复杂数据类型(Complex datatypes)

类型名说明典型用途
objectJSON 对象,可嵌套多层字段复杂文档结构,如用户信息中嵌套地址对象
nested嵌套类型,支持多值数组中每个元素作为独立对象查询商品规格列表、订单明细列表

三. 特殊数据类型(Specialized datatypes)

类型名说明典型用途
geo_point地理坐标点(经纬度)地理位置定位、地图检索
geo_shape复杂地理形状(多边形、圆等)地理范围查询、地理围栏
ipIPv4 或 IPv6 地址服务器 IP、客户端 IP
completion自动补全建议类型搜索自动补全
token_count统计分词后词数统计分析
murmur3MurmurHash3 哈希码唯一标识生成
binary二进制数据图片、文件二进制存储
join父子关系建模一对多、多对多文档关联

HTTP 请求方法介绍

方法作用典型 Elasticsearch 场景
GET获取数据或状态,不改变数据查询文档、获取索引信息、获取集群状态
POST提交数据,创建资源或执行复杂操作新增文档(自动生成ID)、执行复杂搜索请求、更新文档(部分更新)、批量操作
PUT创建或完全替换资源创建索引、创建或覆盖指定ID的文档
DELETE删除资源删除文档、删除索引、删除模板
PATCHElasticsearch 不常用ES 原生API一般不用 PATCH,但理论上用于部分更新(ES用POST+_update代替)
HEAD获取资源的元信息,不返回主体检查索引是否存在,检查文档是否存在

Endpoint 端点接口介绍

API 路径作用说明典型用途
/{index}/_doc文档增删改查的基础接口添加文档(POST)、获取文档(GET)、删除文档(DELETE)
/{index}/_update文档的部分更新局部修改文档字段,执行脚本等
/{index}/_search搜索接口全文检索、复杂查询
/{index}索引的创建、删除、获取索引信息等创建索引(PUT)、删除索引(DELETE)、获取索引信息(GET)
/_bulk批量操作接口批量新增、更新、删除文档
/_mapping获取或更新索引映射(字段类型定义)查看或调整字段类型和属性
/_settings获取或更新索引设置调整分片、副本、刷新频率等
/_cat便捷的索引、节点、集群信息展示接口查看集群状态、索引列表、节点健康等
/_cluster集群级别管理接口查看集群健康、状态,管理集群设置
/_alias管理索引别名创建、删除、查看别名
/_count统计文档数量查询符合条件的文档总数
/_reindex索引重建将数据从一个索引复制到另一个索引
/_flush手动刷新索引强制把缓冲区数据写入磁盘,减少数据丢失风险

索引 (Index)(表) 相关命令

索引 就是 mysql 中的表,索引 = 表

创建索引

方式一:// 只创建索引结构

PUT /my_index                  // my_index:自定义的索引(表)名称
{"mappings": {                // mappings 创建索引的关键字,表示 映射定义开始"properties": {            // properties 创建索引的关键字,表示 定义字段集合"name": {                // 自定义字段名称"type": "text"         // 字段类型,text:分词字符串 全文检索字符串},"age": {                 // 自定义字段名称"type": "integer"      // 字段类型,integer:32位整数类型},"status": {              // 自定义字段名称"type": "keyword"      // 字段类型,keyword:不分词字符串,用于精确匹配}}}
}

方式二:// 添加一行数据,索引结构不存在时自动创建索引。缺点:自动映射不够精准,复杂场景建议手动建索引。

POST /my_index/_doc
{"name": "Alice","age": 25
}

查询索引列表

查询所有索引

GET /_cat/indices

查询指定的索引,* 通配符的方式,通配符可以使用在开头、中间、结尾

GET /_cat/indices/前缀*?v
GET /_cat/indices/*后缀?v
GET /_cat/indices/*xxx*yyy*?v
GET /_cat/indices/*x*y*z*?v

查看索引数据结构

查看表结构

命令:

GET /索引名/_mapping

示例:

GET /my_index/_mapping

修改索引数据结构

!!! 不能直接修改已存在字段的类型

一旦索引创建且字段映射确定后,字段的类型是固定的,不能修改字段类型,比如把 text 改成 keyword 是不允许的。或者删除一个字段也是不可以的。
如果要修改字段类型,通常需要新建一个索引,重新定义 mapping,然后把数据 reindex(迁移)过去。

reindex 迁移示例:

需求:假设旧索引有字段 fullname,新索引改成了 name。

原索引:

PUT /old_users
{"mappings": {"properties": {"fullname": { "type": "text" },"age":      { "type": "integer" },"status":   { "type": "keyword" }}}
}

新索引:

PUT /new_users
{"mappings": {"properties": {"name":    { "type": "text" },"age":     { "type": "integer" },"status":  { "type": "keyword" },"email":   { "type": "keyword" }}}
}

迁移命令:

POST /_reindex
{"source": {"index": "old_users"},"dest": {"index": "new_users"},"script": {"source": """ctx._source.name = ctx._source.remove('fullname');"""}
}# ctx._source.name 新索引 新字段
# ctx._source.remove('fullname') 旧索引 旧字段

删除索引

删除表

删除指定的索引

命令:

DELETE /索引名

删除多个索引

命令:使用 * 通配符

DELETE /*索*引*名*

添加数据 相关命令

添加一条数据,不指定id,es自动生成id

命令:

POST /my_index/_doc            // my_index: 索引名,_doc: 添加数据关键字
{"name": "Alice",             // key: value,字段名和字段数据"age": 25,"status": "active","joinDate": "2025-08-11"
}

添加成功返回

{"_index": "my_index","_id": "vDD0lpgBikDxJFOszVbZ",        // id 自动生成"_version": 1,"result": "created","_shards": {"total": 2,"successful": 1,"failed": 0},"_seq_no": 0,"_primary_term": 1
}

添加一条数据,指定id

PUT:指定 _id(这里是 1),如果 ID 存在,会覆盖(替换整条记录),如果 ID 不存在,会添加

命令:

POST /my_index/_doc/1            // my_index: 索引名,_doc: 添加数据关键字,1:你指定的id
{"name": "Bob",                 // key: value,字段名和字段数据"age": 30,"status": "inactive","joinDate": "2024-01-01"
}

添加成功返回

{"_index": "my_index","_id": "1",                // id 自己指定的"_version": 1,"result": "created","_shards": {"total": 2,"successful": 1,"failed": 0},"_seq_no": 1,"_primary_term": 1
}

局部插入或更新

  • 如果 _id=3 的文档已经存在
    • 用 doc 里的内容部分更新它(只改 age 字段,不会影响其他字段)。
  • 如果 _id=3 的文档不存在
    • 直接把 doc 里的内容当作一个新文档插入(相当于 upsert 功能)。
POST /my_index/_update/3        // _update:更新数据关键字
{"doc": { "age": 28 },"doc_as_upsert": true         // 开启更新插入
}

批量添加

跳过


查询数据 相关命令

查询类型说明

一、基础查询类型(基础检索)

查询类型说明备注
match_all返回所有文档全量扫描
match全文匹配,分词后匹配适合 text 类型字段
term精确匹配(不分词)适合 keyword、数字等
terms多值精确匹配多个精确值匹配
range范围查询(如大于、小于、介于)数字、日期等
exists判断字段是否存在
prefix前缀匹配
wildcard通配符匹配(支持 *?慎用,性能较差
regexp正则表达式匹配性能较差
fuzzy模糊匹配(拼写错误容忍)
ids根据文档 ID 精确查找

二、逻辑组合查询(复合查询)

查询子句说明备注
bool复合查询,组合多个子句mustshouldmust_notfilter
- must必须匹配,逻辑 AND查询条件必须满足
- should应该匹配,逻辑 OR满足一条即匹配
- must_not必须不匹配,逻辑 NOT排除满足条件文档
- filter过滤查询,不计分,缓存优化用于限制结果
constant_score包裹查询,返回固定分数,忽略相关性评分用于过滤条件
dis_max多个查询取最高得分

三、全文检索增强

查询类型说明
multi_match多字段全文匹配
common_terms高频词优化,减少高频词干扰
query_string支持复杂查询语法
simple_query_string简化版查询语法,容错性强

四、地理位置相关查询

查询类型说明
geo_distance距离查询
geo_bounding_box矩形区域查询
geo_polygon多边形区域查询

五、脚本和特殊查询

查询类型说明
script自定义脚本查询
function_score自定义相关性评分
more_like_this找相似文档
percolate反向查询,存储查询以匹配新文档
nested嵌套文档查询
has_child / has_parent父子文档关系查询
span_queries精细控制词语位置的查询

六、查询参数与选项

参数说明
size返回文档数量,默认 10
from分页起始位置
_source控制返回字段
sort排序字段和顺序
timeout查询超时时间
track_total_hits是否精确统计总命中数,默认最多10000
min_score过滤分数低于阈值的文档
highlight高亮显示查询关键字
collapse按字段折叠结果(类似 SQL 的 group by)

七、常用聚合(Aggregation)

聚合类型说明
aggs / aggregations聚合的入口,定义统计分析操作。统计、分组、分桶
buckets聚合结果中的分组容器,每个桶代表一类数据,里面有符合条件的文档集合
terms按字段分组统计
range数值或日期范围分组
- rangesrange 聚合中定义的区间数组,比如 { "from": 20, "to": 30 }
- key聚合结果返回的每个桶的名称,方便引用
- doc_count聚合结果返回的桶中符合条件的文档数量
metrics计算数值统计,如 avg, sum, min, max
date_histogram时间分桶
nested嵌套结构聚合
filter条件过滤聚合

八、操作符

操作符说明
range范围查询
- gte大于等于
- gt大于
- lte小于等于
- lt小于

查询指定索引的全部数据

相当于 mysql 的:select 

示例:

GET /索引名/_search        // _search:查询关键字       
{"query": {"match_all": {}},"size": 20
}

说明:

match_all 会返回所有文档,但是你只能看到10条数据。

默认情况下,Elasticsearch 出于性能考虑,一次查询只返回 10 条记录,而不是把所有数据都一下子返回给你。

如果你想一次性多拿一些,可以加上 size 参数。size 不能无限大,太大会影响性能。

如果数据量很大,要分页查,可以用 from + size:

分页查询 命令:

GET /索引名/_search
{"from": 0,                // from 表示跳过多少条"size": 20,               // size 表示取多少条"query": {"match_all": {}}
}

精确查询

term:精确查询的关键字

示例:

GET /索引名/_search
{"query": {"term": {"status": "active"        // 查询 字段 status 的值是 active 的数据,适合 keyword 类型}}
}

全文检索(分词查询)

全文检索一个字段

match:单字段,全文检索的关键字,适合 text 类型

示例:

GET /索引名/_search
{"query": {"match": {"description": "quick fox"        // description 要查询的字段}}
}

说明:

  • ​​​​​​Elasticsearch 会先对字段 description 里的文本和查询语句 "quick fox" 都做分词处理,比如拆成两个词 "quick" 和 "fox"。
  • 然后它会找出所有包含这两个词(或其中一个词,相关度越高的排前面)的文档。
  • 这种查询会根据词出现的频率、位置等因素计算相关度分数,结果按相关度排序。

全文检索多个字段

示例一:

multi_match:多字段,全文检索的关键字,适合 text 类型

GET /索引名/_search
{"query": {"multi_match": {"query": "quick fox","fields": ["description", "title"]}}
}

说明:

  • query: 你要搜索的关键词 "quick fox"
  • fields: 指定多个字段一起匹配,这里是 "description" 和 "title"
  • Elasticsearch 会在这两个字段中分别分词匹配,然后结合相关度返回结果。

示例二:

bool + should 组合

GET /索引名/_search
{"query": {"bool": {"should": [{ "match": { "description": "quick fox" } },{ "match": { "title": "quick fox" } }]}}
}

说明:

  • 是更通用的复合查询写法,表示文档满足任意一个字段匹配即可。

  • 每个子查询独立执行,相关性得分相加。

  • 可灵活组合更多复杂条件。

multi_match 和 bool + should 组合 的区别

  • 如果只是简单地对多个字段全文搜索,multi_match 推荐使用,写法简洁且功能丰富。
  • 如果需要更复杂的逻辑控制,比如不同字段不同查询类型、权重调整,或者要结合其它条件,使用 bool + should 更灵活。

组合查询

多条件查询

示例:

GET /索引名/_search
{"query": {"bool": {"must": [{ "term": { "status": "active" } },{ "range": { "age": { "gte": 18 } } }],"must_not": [{ "term": { "name": "Bob" } }],"should": [{ "match": { "description": "developer" } }],"filter": [{ "exists": { "field": "email" } }]}}
}

说明:

  • must (必须满足)
    • 表示:status 字段的值必须是 "active",同时 age 字段的值必须大于等于 18。
  • must_not:必须不满足(排除)
    • 表示:排除掉 name 字段的值是 "Bob" 的文档。
  • should:满足则加分,满足1条即可(尽量满足)
    • 表示:如果文档的 description 字段的值中包含 "developer",它会被认为更相关,得分更高,但不满足也没关系。
  • filter:过滤条件,不影响评分,性能优
    • 表示:只匹配那些有 email 字段存在的文档。

范围查询

示例:

查询日期范围内的数据

GET /索引名/_search
{"query": {"range": {"joinDate": {"gte": "2024-01-01","lte": "2025-12-31"}}}
}

分页查询

from + size 组合

示例:

跳过前10条,返回后面10条。

GET /索引名/_search
{"from": 10,"size": 10,"query": {"match_all": {}}
}

排序

sort 排序关键字

示例:

GET /索引名/_search
{"sort": [{ "age": "desc" },{ "_score": "desc" }],"query": {"match_all": {}}
}

说明:

  • 先按年龄降序,再按相关度降序。
  • _score:当你执行搜索查询时,Elasticsearch 会根据查询条件计算每个匹配文档的相关度分数(score)。这个分数越高,说明该文档与查询越相关,越匹配用户的搜索意图。_score 是这个分数的具体数值。

高亮显示

highlight:高亮关键字

示例:

GET /索引名/_search
{"query": {"match": { "description": "quick fox" }},"highlight": {"fields": {"description": {}}}
}

返回结果:

{"_source": {"name": "Alice","age": 25,"status": "active","joinDate": "2025-08-11","description": "The quick brown fox jumps over the lazy dog"},"highlight": {"description": ["The <em>quick</em> brown <em>fox</em> jumps over the lazy dog"]}
}

说明:

  • highlight:这是高亮设置,告诉 Elasticsearch 需要对 description 字段中匹配的关键词做高亮处理。默认用 <em></em> 标签包裹匹配的词(你可以自定义标签)。
  • 使用 highlight 后,返回的文档中会多一个 highlight 字段。前端拿到这个 highlight.description 的内容,可以用来在页面上用颜色、加粗等方式突出显示关键词,提升用户体验。

聚合查询

示例:

按年龄段分组统计数量

GET /my_index/_search
{"size": 0,"aggs": {"age_ranges": {"range": {"field": "age","ranges": [{ "to": 20 },{ "from": 20, "to": 30 },{ "from": 30 }]}}}
}

返回结果:

"aggregations": {"age_ranges": {"buckets": [{ "key": "*-20", "to": 20, "doc_count": 15 },{ "key": "20-30", "from": 20, "to": 30, "doc_count": 40 },{ "key": "30-*", "from": 30, "doc_count": 25 }]}
}

说明:

  • "size": 0:不返回匹配的具体文档,只返回聚合结果。这样可以节省网络传输,适合只想看统计结果。
  • aggs:aggs 是 aggregations(聚合) 的简写。用于对查询结果进行统计分析,比如计算总数、求平均、分组、范围统计等。返回的是统计结果,不是具体文档内容。
  • age_ranges:是你给这个聚合起的名字,名字可以随便取。
  • range:表示使用范围聚合
  • "field": "age":表示要聚合的字段是 age 字段。
  • ranges:聚合条件
    • to: 20:统计所有 age 小于 20 的文档数量。
    • from: 20, to: 30:统计所有 20 <= age < 30 的文档数量。
    • from: 30:统计所有 age 大于等于 30 的文档数量。
http://www.xdnf.cn/news/1276993.html

相关文章:

  • Android APK 使用OpenGl 绘制三角形源码
  • Spring Boot 全局异常处理与日志监控实战
  • 智能体革命:网络安全人的角色重塑与突围指南
  • 井字游戏的强化学习
  • 复现论文《基于Retinex理论和深度学习的低照度图像增强算法研究》
  • CompletableFuture实现Excel 多个sheet页批量导出
  • 【模板】拓扑排序
  • 【嵌入式硬件实例】-555定时器PWM调光电路
  • 通过Certbot自动申请更新HTTPS网站的SSL证书
  • 字节:计算机存储单位
  • Spring Cloud系列—OpenFeign远程调用
  • 【东枫科技】FR3 可扩展测试平台,适用于 6G 研究与卫星通信,高达 1.6 GHz 的带宽
  • 【Html网页模板】炫酷科技风公司首页
  • 正确使用SQL Server中的Hint(10)—Hint简介与Hint分类及语法(1)
  • strace的常用案例
  • GPT-5与中国AI发展(DeepSeek R1视角)
  • FFmpeg实现音视频转码
  • QT的常用控件说明
  • 【从源码角度深度理解 Python 的垃圾回收机制】:第1课引用计数篇
  • C++高频知识点(二十)
  • 电脑使用“碎片整理”程序的作用
  • Vue.js设计于实现 - 概览(二)
  • Vue 事件冒泡处理指南:从入门到精通
  • vue2升级vue3:单文件组件概述 及常用api
  • 基于VuePress2开发文档自部署及嵌入VUE项目
  • 【数据分析】循环移位岭回归分析:光遗传学冻结行为模式研究
  • 2025华数杯比赛还未完全结束!数模论文可以发表期刊会议
  • SAP学习笔记 - 开发57 - RAP开发 Managed App RAP action 之 Accept Travel 和 Reject Travel
  • special topic 8 (2) and topic 9 (1)
  • 一键复制产品信息到剪贴板