Elasticsearch 基础使用教程:从 MySQL 视角理解 ES

Elasticsearch 基础使用教程:从 MySQL 视角理解 ES

如果你熟悉 MySQL,学习 Elasticsearch 会容易很多——因为两者的很多概念是可以类比的。本文就用 MySQL 的思维方式来理解 Elasticsearch,帮你快速上手。


一、核心概念对照表

先看一张核心概念对照表,建立整体认知:

MySQL Elasticsearch 说明
Database(数据库) Index(索引) 数据的逻辑容器
Table(表) Index(索引) ES 中 Index 既相当于数据库,也相当于表
Row(行) Document(文档) 一条具体的数据记录
Column(列) Field(字段) 数据的一个属性
Schema(表结构) Mapping(映射) 定义字段类型和存储方式
INSERT POST / PUT 插入数据
SELECT GET / POST _search 查询数据
UPDATE POST _update 更新数据
DELETE DELETE 删除数据
Index(索引) 分片 + 副本 MySQL 的索引是加速查询;ES 的分片是数据分片存储

💡 关键区别:MySQL 是关系型数据库,强调事务和关联;Elasticsearch 是搜索引擎,强调全文检索和实时分析。


二、创建”表”(创建索引)

MySQL 方式

CREATE TABLE users (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(100),
    email VARCHAR(100),
    age INT,
    created_at DATETIME,
    INDEX idx_name (name),
    INDEX idx_email (email)
);

Elasticsearch 方式

在 ES 中,创建索引可以显式定义 Mapping,也可以让 ES 自动推断:

# 创建索引并定义 Mapping(推荐)
PUT /users
{
  "mappings": {
    "properties": {
      "name": { "type": "text" },
      "email": { "type": "keyword" },
      "age": { "type": "integer" },
      "created_at": { "type": "date" }
    }
  }
}

类型说明

  • text:全文搜索类型,会被分词(类似 MySQL 的 FULLTEXT 索引)
  • keyword:精确匹配类型,不分词(类似 MySQL 的普通索引)
  • integerlongfloat:数值类型
  • date:日期类型
  • boolean:布尔类型

三、插入数据(INSERT → POST)

MySQL 方式

INSERT INTO users (name, email, age, created_at) 
VALUES ('张三', '[email protected]', 28, '2024-01-15 10:30:00');

INSERT INTO users (name, email, age, created_at) 
VALUES ('李四', '[email protected]', 32, '2024-01-16 14:20:00');

INSERT INTO users (name, email, age, created_at) 
VALUES ('王五', '[email protected]', 25, '2024-01-17 09:00:00');

Elasticsearch 方式

# 插入单条文档(ES 自动生成 ID)
POST /users/_doc
{
  "name": "张三",
  "email": "[email protected]",
  "age": 28,
  "created_at": "2024-01-15T10:30:00"
}

# 插入单条文档(指定 ID)
PUT /users/_doc/1
{
  "name": "张三",
  "email": "[email protected]",
  "age": 28,
  "created_at": "2024-01-15T10:30:00"
}

# 批量插入
POST /_bulk
{"index": {"_index": "users"}}
{"name": "张三", "email": "[email protected]", "age": 28, "created_at": "2024-01-15T10:30:00"}
{"index": {"_index": "users"}}
{"name": "李四", "email": "[email protected]", "age": 32, "created_at": "2024-01-16T14:20:00"}
{"index": {"_index": "users"}}
{"name": "王五", "email": "[email protected]", "age": 25, "created_at": "2024-01-17T09:00:00"}

四、查询数据(SELECT → _search)

4.1 查询所有数据

MySQL

SELECT * FROM users;

Elasticsearch

GET /users/_search
{
  "query": {
    "match_all": {}
  }
}

4.2 条件查询

MySQL

SELECT * FROM users WHERE name = '张三';

Elasticsearch

# 精确匹配(keyword 类型)
GET /users/_search
{
  "query": {
    "term": {
      "email": "[email protected]"
    }
  }
}

# 全文搜索(text 类型,会被分词)
GET /users/_search
{
  "query": {
    "match": {
      "name": "张三"
    }
  }
}

4.3 范围查询

MySQL

SELECT * FROM users WHERE age >= 25 AND age < 30;

Elasticsearch

GET /users/_search
{
  "query": {
    "range": {
      "age": {
        "gte": 25,
        "lt": 30
      }
    }
  }
}

4.4 多条件组合

MySQL

SELECT * FROM users 
WHERE age >= 25 
AND (name LIKE '%张%' OR email LIKE '%example%')
ORDER BY created_at DESC
LIMIT 10;

Elasticsearch

GET /users/_search
{
  "query": {
    "bool": {
      "must": [
        { "range": { "age": { "gte": 25 } } }
      ],
      "should": [
        { "match": { "name": "张" } },
        { "wildcard": { "email": "*example*" } }
      ],
      "minimum_should_match": 1
    }
  },
  "sort": [
    { "created_at": { "order": "desc" } }
  ],
  "size": 10
}

bool 查询说明

  • must:必须满足(类似 AND)
  • should:满足任意一个即可(类似 OR)
  • must_not:必须不满足(类似 NOT)
  • filter:过滤条件,不参与评分(性能更好)

五、更新数据(UPDATE → _update)

MySQL 方式

UPDATE users SET age = 29 WHERE id = 1;

Elasticsearch 方式

# 部分更新
POST /users/_update/1
{
  "doc": {
    "age": 29
  }
}

# 脚本更新(更灵活)
POST /users/_update/1
{
  "script": {
    "source": "ctx._source.age += params.increment",
    "params": {
      "increment": 1
    }
  }
}

⚠️ 注意:ES 的更新操作实际上是”标记删除 + 重新写入”,频繁更新会影响性能。


六、删除数据(DELETE → DELETE)

MySQL 方式

DELETE FROM users WHERE id = 1;

DELETE FROM users WHERE age < 20;

-- 删除整个表数据(保留表结构)
TRUNCATE TABLE users;

Elasticsearch 方式

# 删除单条文档
DELETE /users/_doc/1

# 按条件删除
POST /users/_delete_by_query
{
  "query": {
    "range": {
      "age": { "lt": 20 }
    }
  }
}

# 删除整个索引(类似 DROP TABLE)
DELETE /users

七、聚合分析(GROUP BY → Aggregations)

MySQL 方式

-- 统计各年龄段的人数
SELECT 
    CASE 
        WHEN age < 20 THEN 'under_20'
        WHEN age >= 20 AND age < 30 THEN '20_29'
        WHEN age >= 30 AND age < 40 THEN '30_39'
        ELSE '40_plus'
    END AS age_group,
    COUNT(*) as count,
    AVG(age) as avg_age
FROM users
GROUP BY age_group;

Elasticsearch 方式

GET /users/_search
{
  "size": 0,
  "aggs": {
    "age_groups": {
      "range": {
        "field": "age",
        "ranges": [
          { "to": 20, "key": "under_20" },
          { "from": 20, "to": 30, "key": "20_29" },
          { "from": 30, "to": 40, "key": "30_39" },
          { "from": 40, "key": "40_plus" }
        ]
      },
      "aggs": {
        "avg_age": {
          "avg": { "field": "age" }
        }
      }
    }
  }
}

常用聚合类型:

MySQL Elasticsearch
COUNT(*) value_count
SUM(field) sum
AVG(field) avg
MAX(field) / MIN(field) max / min
GROUP BY terms(分组)、range(范围分组)

八、分页查询

MySQL 方式

-- 第 1 页,每页 10 条
SELECT * FROM users LIMIT 0, 10;

-- 第 2 页
SELECT * FROM users LIMIT 10, 10;

-- 第 3 页
SELECT * FROM users LIMIT 20, 10;

Elasticsearch 方式

# 使用 from + size(类似 MySQL LIMIT)
GET /users/_search
{
  "from": 0,
  "size": 10,
  "query": { "match_all": {} }
}

# 第 2 页
GET /users/_search
{
  "from": 10,
  "size": 10,
  "query": { "match_all": {} }
}

# 深分页(数据量大时推荐使用 search_after)
GET /users/_search
{
  "size": 10,
  "query": { "match_all": {} },
  "sort": [
    { "created_at": "desc" },
    { "_id": "asc" }
  ],
  "search_after": [1704067200000, "abc123"]
}

⚠️ 注意:ES 的 from + size 默认限制最大 10000 条,深分页建议使用 search_afterscroll API。


九、MySQL vs ES:什么时候用哪个?

场景 推荐 原因
事务处理(订单、支付) MySQL ES 不支持事务
复杂关联查询 MySQL ES 关联能力有限
全文搜索 Elasticsearch ES 天生为搜索而生
日志分析 Elasticsearch ES 写入和聚合性能强
实时监控大屏 Elasticsearch ES 聚合查询速度快
主数据存储 MySQL ES 数据可能丢失(近实时)

常见架构:MySQL 作为主存储,数据同步到 ES 做搜索和分析。

┌──────────┐     同步      ┌──────────────┐
│  MySQL   │  ──────────►  │ Elasticsearch │
│ (主存储)  │               │  (搜索/分析)  │
└──────────┘               └──────────────┘
     │                            │
     │                            │
     ▼                            ▼
  业务写入                    搜索/分析查询

十、快速参考:常用 API

# 查看所有索引
GET /_cat/indices?v

# 查看索引 mapping
GET /users/_mapping

# 查看索引设置
GET /users/_settings

# 查看集群健康状态
GET /_cluster/health

# 查看节点信息
GET /_cat/nodes?v

# 查看索引统计
GET /users/_stats

总结

从 MySQL 视角理解 Elasticsearch:

  1. Index ≈ Database + Table:一个索引就是一个数据容器
  2. Document ≈ Row:JSON 格式的一行数据
  3. Mapping ≈ Schema:定义字段类型
  4. Query DSL ≈ SQL:用 JSON 格式表达查询条件
  5. Aggregation ≈ GROUP BY:强大的聚合分析能力

掌握这些对应关系,你就能快速上手 Elasticsearch 了!


下一篇预告:Elasticsearch 进阶使用 —— 复合查询、脚本、分析器详解