第四阶段 33 · index / mapping 管理(建索引、别名、reindex)

33 · index / mapping 管理(建索引、别名、reindex)

阶段:第四阶段 / 写入与索引管理

ES:建索引 / mapping / 别名 / reindex | PostgreSQL:DDL、CREATE TABLE、视图、表重建


1. 概念

索引管理相当于数据库的 DDL:

ES 操作 SQL 对照
PUT /index + mapping CREATE TABLE + 列定义
别名 alias 视图 / 可切换的表名
reindex INSERT INTO new SELECT * FROM old(表重建)
PUT /index/_mapping ALTER TABLE ADD COLUMN

本项目建索引入口:InsertToEsTask.createIndex → CreateSalesIndexHandler,

mapping 从 mappings/*.json(如 salesdata_idx.json)读取。


2. PostgreSQL 对照

sql 复制代码
CREATE TABLE salesdata (
  invoice_number varchar,
  net_amount     numeric,
  invoice_dt     date
);

-- 加列(ES 只能加不能改类型)
ALTER TABLE salesdata ADD COLUMN customer_group varchar;

-- 视图切换(类比别名)
CREATE VIEW salesdata_current AS SELECT * FROM salesdata_v2;

3. ES DSL

复制代码
# 建索引 + settings + mapping
PUT salesdata_idx
{
  "settings": { "number_of_shards": 3, "number_of_replicas": 1 },
  "mappings": {
    "properties": {
      "invoice_number": { "type": "keyword" },
      "net_amount":     { "type": "double" },
      "invoice_dt":     { "type": "date", "format": "yyyy-MM-dd" }
    }
  }
}

# 追加字段(不能改已有字段类型)
PUT salesdata_idx/_mapping
{ "properties": { "customer_group": { "type": "keyword" } } }

# 别名切换(原子)
POST _aliases
{
  "actions": [
    { "remove": { "index": "salesdata_v1", "alias": "salesdata" } },
    { "add":    { "index": "salesdata_v2", "alias": "salesdata" } }
  ]
}

# reindex:老索引数据搬到新索引
POST _reindex
{ "source": { "index": "salesdata_v1" }, "dest": { "index": "salesdata_v2" } }

4. Spring Boot 实现

java 复制代码
@Component
public class Doc33IndexAdmin {

    @Autowired
    private ElasticsearchClient elasticsearchClient;

    /** 建索引 + mapping(简化版,本项目实际读 mappings/*.json) */
    public void createIndex(String indexName) throws IOException {
        boolean exists = elasticsearchClient.indices()
                .exists(e -> e.index(indexName)).value();
        if (exists) {
            return;
        }
        elasticsearchClient.indices().create(c -> c
                .index(indexName)
                .settings(st -> st.numberOfShards("3").numberOfReplicas("1"))
                .mappings(m -> m
                        .properties("invoice_number", p -> p.keyword(k -> k))
                        .properties("net_amount", p -> p.double_(d -> d))
                        .properties("invoice_dt", p -> p.date(d -> d.format("yyyy-MM-dd")))));
    }

    /** 追加字段:类比 ALTER TABLE ADD COLUMN */
    public void addKeywordField(String indexName, String field) throws IOException {
        elasticsearchClient.indices().putMapping(m -> m
                .index(indexName)
                .properties(field, p -> p.keyword(k -> k)));
    }

    /** 原子切换别名 */
    public void switchAlias(String alias, String oldIndex, String newIndex) throws IOException {
        elasticsearchClient.indices().updateAliases(a -> a
                .actions(ac -> ac.remove(r -> r.index(oldIndex).alias(alias)))
                .actions(ac -> ac.add(ad -> ad.index(newIndex).alias(alias))));
    }
}

与本项目对照:建索引逻辑见 CreateSalesIndexHandler,mapping 新增字段时

参考 ADD_FIELD_SKILL 里 ES 部分(在 mapping 的 properties 追加字段)。


5. 坑与最佳实践

  1. mapping 不可改已有字段类型:改类型只能新建索引 + reindex + 切别名。
  2. 用别名解耦 :应用只认别名(如 salesdata),底层索引版本切换对上层透明、零停机。
  3. 动态映射风险:生产索引建议显式 mapping,或关掉动态映射,避免字段类型被自动猜错。
  4. 分片数建后不可改 :number_of_shards 定死,需重新规划只能 reindex;副本数可动态调。
  5. reindex 期间双写或停写:保证新老索引数据一致,切别名前校验文档数。

阶段小结

第四阶段完成后,你应该能:单文档增删改、bulk 批量写、按条件批量更新/删除、

建索引与 mapping、用别名做零停机切换、用 reindex 重建索引。

相关推荐
gb42152874 小时前
向量数据库多模态特性
数据库
泡海椒4 小时前
数据占比展示:jquick-pdf饼图动态数据渲染PDF教程
数据库·oracle·pdf
大连好光景5 小时前
向量数据库的工作流程详解
数据库·milvus
catchadmin5 小时前
用 Jev 与 Laravel AI SDK 检测垃圾邮件和自动回复
数据库·人工智能·laravel
吠品6 小时前
CSS图片模糊过渡:一个transition加filter就够
java·数据库·notepad++
梦想不只是梦与想7 小时前
对象存储服务器vs数据库
数据库·对象存储·图片存储
Ivanqhz7 小时前
正余弦位置编码(Sinusoidal Positional Encoding)
java·linux·数据库
Ivanqhz8 小时前
层归一化、残差、前馈网络与激活函数简述
服务器·数据库·人工智能·深度学习·算法
Java后端的Ai之路8 小时前
Python进阶探索23 - Python中的Time与Datetime模块
开发语言·数据库·python·datetime·time
通信瓦工9 小时前
利用浊度和电导率测量确定乙二醇基流体的质量
网络·数据库·ai