索引的概念
在ES中,索引(Index) 是核心的数据存储和检索单元,其本质是一组结构相似的文档(Document)的集合,同时包含了文档的元数据(如字段类型、分词器配置)和检索所需的 “倒排索引” 结构。ES软件的索引类似于MySQL中数据库的概念,创建一个索引,类似于创建一个数据库,但功能和设计更贴合全文检索场景。它不仅是数据的容器,还内置了分词、倒排索引等机制,支撑 ES 高效的搜索能力。
索引的核心作用
- 结构化存储:通过 Mapping 约束字段类型,避免数据混乱;
- 高效检索:自动为文本字段构建倒排索引(从 “关键词” 映射到 “文档 ID” 的结构),实现毫秒级全文搜索;
- 分片与副本:支持水平拆分(分片)和数据冗余(副本),兼顾性能与高可用;
- 近实时(NRT):数据写入后秒级可检索,平衡实时性与性能。
索引的关键属性
- 分片
ES 索引的数据会被拆分为多个分片(Shard),每个分片本质是一个独立的 “小型索引”,可分布在不同节点上,实现:
- 水平扩展:数据量增大时,增加分片数量(需在创建索引时指定,后续不可修改);
- 并行查询:查询时可同时在多个分片上执行,提升效率。
分片类型
- 主分片(Primary Shard):数据写入的 “主节点”,负责数据的索引和存储,每个索引的主分片数量在创建时固定(默认 1 个);
- 副本分片(Replica Shard):主分片的 “备份”,仅用于查询和故障恢复(主分片故障时,副本可升级为主分片),数量可动态修改(默认 1 个,即每个主分片对应 1 个副本)。
示例:若索引配置为 “3 个主分片 + 1 个副本”,则总分片数为 3(主) + 3(副)= 6,数据会均匀分布到 3 个主分片,每个主分片的副本存储相同数据。
- 映射
索引包含一个映射 (Mapping),它定义了索引的数据结构,具体如下:
2.1:字段类型
- 字符串类型:text:可分词的文本,用于全文搜索,该文本会被分词器(Analyzer)拆分成倒排索引中的词条(Terms)。keyword:不可分词的文本,用于精确匹配。
- 数值类型:long、integer、short、byte、double、float、half float、scaled float
- 日期类型:date
- 布尔类型:boolean
- 二进制类型:binary
- 对象类型:object
- 嵌套对象类型:nested,
除了这些还有其他字段类型,这里不一 一举例了。
2.2:分词器(Analyzer):指定文本字段的分词规则(如中文用 ik_max_word,英文用默认的 standard)。
2.3:索引开关(index):控制字段是否参与检索(true 可检索,false 仅存储不检索);
2.4:其他规则:如日期格式、字段是否可排序、是否存储原始值等。
下面定义一个简单的映射结构
{"mappings": {"properties": {"product_name": { "type": "text", // 可分词,支持全文搜索"analyzer": "ik_max_word"// 中文分词器(需提前安装 IK 插件)},"product_id": { "type": "keyword", // 不可分词,用于精确匹配(如根据 ID 查询)"index": true},"price": { "type": "double" // 数值类型,支持范围查询(如价格 > 100)},"create_time": { "type": "date", "format": "yyyy-MM-dd HH:mm:ss" // 日期格式}}}
}
- 别名(Alias)
索引别名是给一个或多个索引起的 “别名”,类似文件系统的软链接,主要用途:
- 隐藏索引名变化:如按日期创建日志索引(log-202405、log-202406),可通过别名 log-current 指向最新索引,查询时无需修改索引名;
- 索引切换无感知:如重建索引(优化 Mapping 或数据)时,可先将新索引准备好,再通过别名切换,业务无停机;
- 多索引聚合查询:一个别名可指向多个索引(如 log-all 指向 log-202405 和 log-202406),查询时自动聚合多索引数据。
例如给索引 product-v1 添加别名 product,后续查询时,用 GET /product/_search 即可访问 product-v1。
POST /_aliases
{"actions": [{"add": {"index": "product-v1","alias": "product"}}]
}
如何检测指定索引是否存在
- 格式:head 索引名称,例如head test_index,执行后若返回状态码是200则表示该索引存在,若返回404则代表不存在。
索引操作类型
注意:
- 索引名称要小写,不能包含特殊字符。
- ES不允许修改已经创建的索引信息。
- 查询和删除不存在的索引会报错。
- 在es7.x及以上版本中,类型名称被启用,默认为_doc。
PUT
- 创建索引并给索引起别名
PUT /product-index{"aliases":{"product-index-1": {} }
}
- 创建索引并指定分片、副本、Mapping 等配置
PUT /product-index
{"settings": {"number_of_shards": 3, // 主分片数量(创建后不可改)"number_of_replicas": 1 // 副本数量(可动态修改)},"mappings": {"properties": {"product_name": { "type": "text", "analyzer": "ik_max_word" },"product_id": { "type": "keyword" },"price": { "type": "double" },"create_time": { "type": "date", "format": "yyyy-MM-dd HH:mm:ss" }}}
}
- 创建或更新文档,如果该索引、类型和 ID 的文档不存在,则会创建一个新文档;如果已存在,则会更新该文档的内容。
PUT /callme/_doc/1
{"name": "动态","count":100
}
- 修改索引配置,仅支持修改可动态调整的配置(如副本数量、刷新间隔等),主分片数量不可改
PUT /product-index/_settings
{"number_of_replicas": 2 // 将副本数量从 1 改为 2
}
GET
- 查询单个索引
GET /product-index
- 查看多个索引
GET /product-index,test-index
- 查询所有索引
方式一:GET _cat/indices
作用:专门用于查看集群中所有索引的元数据信息(非文档数据),是最常用的索引列表查询方式。
返回数据:索引名称、健康状态(green/yellow/red)、分片数、文档数量、存储大小等。
方式二:GET /*
*是通配符,表示匹配所有索引,该请求会查询所有索引中的文档数据(类似搜索操作)。所有索引中匹配条件的文档(默认返回 10 条),包含文档内容、得分等搜索结果。
注意:
- 不建议在生产环境直接使用,可能因索引过多导致性能问题。
- 实际是执行搜索操作,而非 “查询索引是否存在” 或 “索引列表”。
方式三:GET /_all
在旧版本(7.x 之前)中,_all 是一个特殊关键字,表示 “所有索引”,作用与 * 类似,用于查询所有索引的文档数据。7.x 及以上版本已废弃 _all,推荐使用 * 代替。
POST
- 创建文档
POST /product-index/_doc/1 //文档ID为1(不指定则自动生成)
{"product_name": "Apple iPhone 15","product_id": "IP15-001","price": 5999.00,"create_time": "2024-05-10 14:30:00"
}
- 全局更新文档
- 若文档存在:会覆盖原文档(相当于全量更新,原字段若未在请求中出现则会被删除)。
- 若文档不存在:会创建新文档(与 PUT 行为一致)。
POST /索引名/_doc/文档ID
{"字段1": "新值1","字段2": "新值2"
}
- 局部更新文档
通过 _update 端点,POST 可以局部修改文档(只更新指定字段,不影响其他字段)
POST /索引名/_update/文档ID
{"doc": {"字段1": "新值1", // 仅更新此字段"字段3": "新值3" // 新增字段}
}
DELETE
- 删除单个索引
DELETE /product-index
- 删除多个索引
DELETE /product-index,test-index
- 删除所有索引
DELETE /_all 或 DELETE /*