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 自动生成,也可以手动指定。
SQL Query DSL MySQL 用 SQL 查询,ES 用 Query DSL(一种 JSON 风格的查询语法)。

数据类型介绍

1. 核心数据类型(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 纳秒精度日期时间 高精度时间戳

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

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

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

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

HTTP 请求方法介绍

方法 作用 典型 Elasticsearch 场景
GET 获取数据或状态,不改变数据 查询文档、获取索引信息、获取集群状态
POST 提交数据,创建资源或执行复杂操作 新增文档(自动生成ID)、执行复杂搜索请求、更新文档(部分更新)、批量操作
PUT 创建或完全替换资源 创建索引、创建或覆盖指定ID的文档
DELETE 删除资源 删除文档、删除索引、删除模板
PATCH Elasticsearch 不常用 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
}

查询索引列表

查询所有索引

bash 复制代码
GET /_cat/indices

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

bash 复制代码
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') 旧索引 旧字段

删除索引

删除表

删除指定的索引

命令:

bash 复制代码
DELETE /索引名

删除多个索引,使用 * 通配符

bash 复制代码
DELETE /*索*引*名*

未完待续