es中的索引

索引的概念

在ES中,索引(Index) 是核心的数据存储和检索单元,其本质是一组结构相似的文档(Document)的集合,同时包含了文档的元数据(如字段类型、分词器配置)和检索所需的 “倒排索引” 结构。ES软件的索引类似于MySQL中数据库的概念,创建一个索引,类似于创建一个数据库,但功能和设计更贴合全文检索场景。它不仅是数据的容器,还内置了分词、倒排索引等机制,支撑 ES 高效的搜索能力。

索引的核心作用

  1. 结构化存储:通过 Mapping 约束字段类型,避免数据混乱;
  2. 高效检索:自动为文本字段构建倒排索引(从 “关键词” 映射到 “文档 ID” 的结构),实现毫秒级全文搜索;
  3. 分片与副本:支持水平拆分(分片)和数据冗余(副本),兼顾性能与高可用;
  4. 近实时(NRT):数据写入后秒级可检索,平衡实时性与性能。

索引的关键属性

  1. 分片

ES 索引的数据会被拆分为多个分片(Shard),每个分片本质是一个独立的 “小型索引”,可分布在不同节点上,实现:

  • 水平扩展:数据量增大时,增加分片数量(需在创建索引时指定,后续不可修改);
  • 并行查询:查询时可同时在多个分片上执行,提升效率。

分片类型

  • 主分片(Primary Shard):数据写入的 “主节点”,负责数据的索引和存储,每个索引的主分片数量在创建时固定(默认 1 个);
  • 副本分片(Replica Shard):主分片的 “备份”,仅用于查询和故障恢复(主分片故障时,副本可升级为主分片),数量可动态修改(默认 1 个,即每个主分片对应 1 个副本)。

示例:若索引配置为 “3 个主分片 + 1 个副本”,则总分片数为 3(主) + 3(副)= 6,数据会均匀分布到 3 个主分片,每个主分片的副本存储相同数据。

  1. 映射

索引包含一个映射 (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" // 日期格式
      }
    }
  }
}
  1. 别名(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"
      }
    }
  ]
}

如何检测指定索引是否存在

  1. 格式:head 索引名称,例如head test_index,执行后若返回状态码是200则表示该索引存在,若返回404则代表不存在。

索引操作类型

注意:

  1. 索引名称要小写,不能包含特殊字符。
  2. ES不允许修改已经创建的索引信息。
  3. 查询和删除不存在的索引会报错。
  4. 在es7.x及以上版本中,类型名称被启用,默认为_doc。

PUT
  1. 创建索引并给索引起别名
PUT /product-index{
  "aliases":{
    "product-index-1": {}  
  }
}
  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" }
    }
  }
}
  1. 创建或更新文档,如果该索引、类型和 ID 的文档不存在,则会创建一个新文档;如果已存在,则会更新该文档的内容。
PUT /callme/_doc/1
{
  "name": "动态",
  "count":100
}
  1. 修改索引配置,仅支持修改可动态调整的配置(如副本数量、刷新间隔等),主分片数量不可改
PUT /product-index/_settings
{
  "number_of_replicas": 2  // 将副本数量从 1 改为 2
}
GET
  1. 查询单个索引
GET /product-index
  1. 查看多个索引
GET /product-index,test-index
  1. 查询所有索引

方式一:GET _cat/indices

作用:专门用于查看集群中所有索引的元数据信息(非文档数据),是最常用的索引列表查询方式。

返回数据:索引名称、健康状态(green/yellow/red)、分片数、文档数量、存储大小等。

方式二:GET /*

*是通配符,表示匹配所有索引,该请求会查询所有索引中的文档数据(类似搜索操作)。所有索引中匹配条件的文档(默认返回 10 条),包含文档内容、得分等搜索结果。

注意:

  • 不建议在生产环境直接使用,可能因索引过多导致性能问题。
  • 实际是执行搜索操作,而非 “查询索引是否存在” 或 “索引列表”。

方式三:GET /_all

在旧版本(7.x 之前)中,_all 是一个特殊关键字,表示 “所有索引”,作用与 * 类似,用于查询所有索引的文档数据。7.x 及以上版本已废弃 _all,推荐使用 * 代替。

POST
  1. 创建文档
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"
}
  1. 全局更新文档
  • 若文档存在:会覆盖原文档(相当于全量更新,原字段若未在请求中出现则会被删除)。
  • 若文档不存在:会创建新文档(与 PUT 行为一致)。
POST /索引名/_doc/文档ID
{
  "字段1": "新值1",
  "字段2": "新值2"
}
  1. 局部更新文档

通过 _update 端点,POST 可以局部修改文档(只更新指定字段,不影响其他字段)

POST /索引名/_update/文档ID
{
  "doc": {
    "字段1": "新值1",  // 仅更新此字段
    "字段3": "新值3"   // 新增字段
  }
}
DELETE
  1. 删除单个索引
DELETE /product-index
  1. 删除多个索引
DELETE /product-index,test-index
  1. 删除所有索引
DELETE /_all 或 DELETE /*
posted @ 2025-09-20 12:08  相遇就是有缘  阅读(26)  评论(0)    收藏  举报