文章八:ElasticSearch特殊数据字段类型解读

Elasticsearch join 类型:实现文档间的父子关联

Elasticsearch 中的 join 类型是唯一支持文档间「父子关系」 的字段类型,核心作用是在同一个索引内建立「父文档」和「子文档」的关联(比如「订单 - 订单明细」「文章 - 评论」),解决 ES 无表关联查询的问题。

一、核心概念(通俗理解)

  • join 类型本质是「字段级的关系定义」,需先声明「关系名称 + 父 / 子文档类型」;
  • 一个索引只能定义一个 join 字段(ES 限制);
  • 父文档和子文档必须存储在同一个分片(通过路由保证,子文档需指定父文档 ID);
  • 子文档可以关联到唯一的父文档,但一个父文档可关联多个子文档(一对多关系)。

二、核心特性

表格

特性 说明
支持的关系 仅「一对多」(一个父文档对应多个子文档),不支持多对多 / 多对一
分片要求 父子文档必须在同一分片(子文档路由值 = 父文档 ID)
查询方式 需用 has_child/has_parent/parent_id 查询关联文档
性能 父子查询比普通查询开销大(需跨文档关联),适合小规模关联场景
适用场景 订单 - 明细、文章 - 评论、商品 - 评价等「一对多、数据量适中」的关联场景

三、完整使用示例(文章 - 评论 父子关系)

场景:存储「文章(父文档)」和「评论(子文档)」,实现关联查询。

1. 创建含 join 类型的索引

需先定义 join 字段,指定「关系名称 + 父 / 子类型」(示例中:article 是父类型,comment 是子类型):

json

复制代码
PUT /article_comment_index
{
  "mappings": {
    "properties": {
      "id": { "type": "integer" },
      "title": { "type": "text" },
      "content": { "type": "text" },
      "comment_content": { "type": "text" },
      "author": { "type": "keyword" },
      // 定义join字段,声明父子关系
      "relation": {
        "type": "join",
        "relations": {
          "article": "comment"  // article是父,comment是子
        }
      }
    }
  }
}
2. 写入父文档(文章)

父文档需指定 join 字段的「父类型」(article):

json

复制代码
// 父文档1:文章ID=1
PUT /article_comment_index/_doc/1  // 文档ID=1(子文档需关联此ID)
{
  "id": 1,
  "title": "Elasticsearch入门",
  "content": "ES是一款分布式搜索引擎",
  "author": "张三",
  "relation": "article"  // 标记为父类型article
}

// 父文档2:文章ID=2
PUT /article_comment_index/_doc/2
{
  "id": 2,
  "title": "Java基础",
  "content": "Java是面向对象语言",
  "author": "李四",
  "relation": "article"
}
3. 写入子文档(评论)

子文档需满足两个核心要求:

  • 指定 join 字段的「子类型 + 父文档 ID」;
  • 通过 routing 参数指定路由值 = 父文档 ID(保证同分片)。

json

复制代码
// 子文档1:关联父文档1(文章1的评论)
PUT /article_comment_index/_doc/3?routing=1  // routing=父文档ID=1
{
  "id": 3,
  "comment_content": "写得很详细,点赞!",
  "author": "王五",
  "relation": {
    "name": "comment",  // 子类型名称
    "parent": "1"       // 关联的父文档ID
  }
}

// 子文档2:关联父文档1(文章1的第二条评论)
PUT /article_comment_index/_doc/4?routing=1
{
  "id": 4,
  "comment_content": "请问join类型性能如何?",
  "author": "赵六",
  "relation": {
    "name": "comment",
    "parent": "1"
  }
}

// 子文档3:关联父文档2(文章2的评论)
PUT /article_comment_index/_doc/5?routing=2
{
  "id": 5,
  "comment_content": "基础知识点很清晰",
  "author": "孙七",
  "relation": {
    "name": "comment",
    "parent": "2"
  }
}

四、join 类型的核心查询方式

场景 1:通过子文档查询父文档(has_child

查询「包含评论作者为王五」的文章:

json

复制代码
GET /article_comment_index/_search
{
  "query": {
    "has_child": {
      "type": "comment",  // 子类型名称
      "query": {
        "term": { "author.keyword": "王五" }  // 子文档的查询条件
      }
    }
  }
}

结果:返回父文档 1(文章 1),因为它有作者为王五的子评论。

场景 2:通过父文档查询子文档(has_parent

查询「文章作者为张三」的所有评论:

json

复制代码
GET /article_comment_index/_search
{
  "query": {
    "has_parent": {
      "parent_type": "article",  // 父类型名称
      "query": {
        "term": { "author.keyword": "张三" }  // 父文档的查询条件
      }
    }
  }
}

结果:返回子文档 3、4(文章 1 的所有评论)。

场景 3:通过父文档 ID 查询子文档(parent_id

查询「父文档 ID=1」的所有评论(最精准):

json

复制代码
GET /article_comment_index/_search
{
  "query": {
    "parent_id": {
      "type": "comment",  // 子类型名称
      "id": "1"           // 父文档ID
    }
  }
}

结果:返回子文档 3、4。

五、join 类型的常见操作与限制

1. 更新父子关系(仅支持修改子文档的父文档)

json

复制代码
// 将子文档5的父文档从2改为1(需指定routing=新父文档ID)
POST /article_comment_index/_update/5?routing=1
{
  "doc": {
    "relation": {
      "name": "comment",
      "parent": "1"
    }
  }
}

2. 核心限制(必看)

  • 一个索引只能定义一个 join 字段;
  • 不支持「子文档再作为父文档」的多级嵌套(如需多级关联,建议用 nested 或数据扁平化);
  • 父子文档必须在同一分片,删除父文档时,子文档不会自动删除(需手动清理);
  • 父子查询性能较差,若子文档数量超 10 万级,建议拆分索引或用应用层关联。

六、join 类型 vs nested 类型(核心区别)

表格

维度 join 类型 nested 类型
数据存储 父 / 子是独立文档 嵌套对象是主文档的一部分
关系支持 一对多(跨文档) 一对多(文档内嵌套)
性能 查询慢(跨文档关联) 查询快(文档内)
数据更新 父 / 子可独立更新 嵌套对象需更新整个主文档
适用场景 父子数据更新频繁、数据量大 嵌套数据更新少、数据量小

总结

  1. join 类型是 ES 实现「同索引跨文档父子关联」的唯一方式,核心定义「父类型 + 子类型」,需保证父子文档在同一分片;
  2. 核心查询语法:has_child(子查父)、has_parent(父查子)、parent_id(按父 ID 查子);
  3. join 类型适合「父子数据独立更新、关联规模适中」的场景,大规模关联建议优先用应用层处理,或选择 nested 类型(文档内嵌套)。

Elasticsearch 字段别名(Alias):字段的「快捷方式」

Elasticsearch 中的字段别名(Field Alias) 是给已有字段定义的「只读快捷方式」,核心作用是为字段提供别名,避免因字段名变更、多字段聚合等场景导致查询 / 聚合语句修改,是 ES 中提升字段使用灵活性的重要特性。

一、核心特性(必掌握)

表格

特性 说明
只读属性 别名仅支持查询 / 聚合,不支持写入(写入仍需用原字段名)
关联关系 一个别名只能指向一个原字段,但一个原字段可被多个别名指向
动态性 可在索引创建后新增 / 修改别名(无需重建索引)
适用字段 支持指向普通字段、object/nested 子字段(如 user.name),不支持指向其他别名
索引要求 别名仅对「已存在的索引」生效,无法在创建文档时通过别名写入数据

二、核心使用场景

  1. 字段名重构 :原字段名变更(如 user_nameusername),通过别名保留旧字段名,无需修改历史查询语句;
  2. 多场景适配 :为同一个字段定义不同别名(如 price 别名 amount),适配不同业务系统的字段命名习惯;
  3. 简化嵌套字段路径 :为多层嵌套字段(如 user.info.address.city)定义别名 user_city,简化查询语法。

三、完整使用示例

1. 创建索引时定义字段别名

json

复制代码
PUT /product_index
{
  "mappings": {
    "properties": {
      "product_id": { "type": "integer" },
      "username": { "type": "keyword" },  // 原字段
      "price": { "type": "float" },       // 原字段
      // 定义字段别名
      "user_name": {                      // 别名1:指向username
        "type": "alias",
        "path": "username"
      },
      "amount": {                         // 别名2:指向price
        "type": "alias",
        "path": "price"
      }
    }
  }
}

2. 向索引写入数据(只能用原字段名)

json

复制代码
PUT /product_index/_doc/1
{
  "product_id": 1,
  "username": "zhangsan",  // 必须写原字段,写user_name会报错
  "price": 99.9            // 必须写原字段,写amount会报错
}

3. 通过别名查询 / 聚合(核心用法)

场景 1:通过别名查询数据

json

复制代码
GET /product_index/_search
{
  "query": {
    "term": {
      "user_name": "zhangsan"  // 用别名查询,等价于查询username
    }
  }
}
场景 2:通过别名做聚合

json

复制代码
GET /product_index/_search
{
  "size": 0,
  "aggs": {
    "avg_amount": {
      "avg": {
        "field": "amount"  // 用别名聚合,等价于聚合price
      }
    }
  }
}
场景 3:为嵌套字段定义别名

json

复制代码
// 先新增嵌套字段
PUT /product_index/_mapping
{
  "properties": {
    "user": {
      "type": "object",
      "properties": {
        "info": {
          "type": "object",
          "properties": {
            "city": { "type": "keyword" }
          }
        }
      }
    },
    // 为嵌套字段定义别名
    "user_city": {
      "type": "alias",
      "path": "user.info.city"
    }
  }
}

// 写入嵌套数据
PUT /product_index/_doc/2
{
  "product_id": 2,
  "user": {
    "info": {
      "city": "Beijing"
    }
  }
}

// 通过别名查询嵌套字段
GET /product_index/_search
{
  "query": {
    "term": {
      "user_city": "Beijing"  // 简化嵌套字段查询
    }
  }
}

4. 新增 / 修改字段别名(索引已创建后)

新增别名

json

复制代码
PUT /product_index/_mapping
{
  "properties": {
    "price_alias": {  // 新增别名
      "type": "alias",
      "path": "price"
    }
  }
}
修改别名(需先删除旧别名,再新增)

ES 不支持直接修改别名,需先删除再重建:

json

复制代码
// 1. 删除旧别名(通过更新mapping,移除别名定义)
PUT /product_index/_mapping
{
  "properties": {
    "amount": null  // 置为null表示删除该别名
  }
}

// 2. 新增新别名(指向其他字段)
PUT /product_index/_mapping
{
  "properties": {
    "amount": {
      "type": "alias",
      "path": "product_id"  // 改为指向product_id
    }
  }
}

5. 查看字段别名(验证配置)

json

复制代码
// 方式1:查看索引完整mapping,包含别名
GET /product_index/_mapping

// 方式2:通过字段别名API查询
GET /product_index/_alias/user_name  // 查询特定别名的指向

四、常见限制与注意事项

  1. 写入限制 :别名仅支持查询 / 聚合,写入、更新、删除操作必须使用原字段名,否则会报错 illegal_argument_exception: alias [xxx] cannot be used in write operations
  2. 嵌套限制 :别名可指向嵌套字段(如 user.info.city),但不能指向别名(即不支持「别名的别名」);
  3. 索引模板:可在索引模板(Index Template)中定义别名,让新建索引自动继承别名配置;
  4. 跨索引别名:字段别名仅作用于单个索引,跨索引的「别名」需使用「索引别名(Index Alias)」(注意区分字段别名和索引别名)。

五、字段别名 vs 索引别名(核心区别)

很多新手会混淆字段别名和索引别名,两者核心差异如下:

表格

维度 字段别名(Field Alias) 索引别名(Index Alias)
作用对象 索引内的单个字段 整个索引(或多个索引)
核心用途 简化字段查询 / 聚合,适配字段名变更 简化索引访问,实现索引无缝切换
写入支持 不支持(仅只读) 支持(可通过别名写入索引)

示例:索引别名是给 product_index_v1 起别名 product_index,字段别名是给 product_index 内的 price 起别名 amount

总结

  1. 字段别名(Alias)是字段的「只读快捷方式」,核心用于简化查询 / 聚合、适配字段名变更,不支持写入;
  2. 一个别名仅指向一个原字段,可在索引创建后新增 / 删除(修改需先删后加);
  3. 支持指向普通字段、嵌套字段,需区分「字段别名」和「索引别名」,前者作用于字段,后者作用于索引。

简单来说,字段别名解决的是「字段名层面的灵活访问」问题,是 ES 中优化字段使用体验的轻量级方案。

Elasticsearch 单值多字段类型(Multi-fields):一个值,多种索引方式

Elasticsearch 中的「单值多字段(Multi-fields)」是指为同一个原始字段值配置多种不同的字段类型 / 分析器,让一个字段值同时支持多种查询场景(比如既做全文检索,又做精准匹配),是处理「同一字段多维度使用」的核心方案。

一、核心概念(通俗理解)

你可以把它想象成:给同一个「原始数据」(比如商品名称 "华为手机Pro"),同时生成「两个不同格式的副本」:

  • 副本 1:按 text 类型 + 中文分词器处理,支持「全文检索」(比如查「华为」「手机」都能匹配);
  • 副本 2:按 keyword 类型处理,支持「精准匹配 / 聚合排序」(比如按完整名称 "华为手机Pro" 分组)。原始字段值只存一份,但 ES 会为每个副本创建独立的倒排索引,满足不同查询需求。

二、核心特性

表格

特性 说明
数据存储 原始值仅存储一份,多字段是「索引层面的副本」,不额外占用存储
字段命名 多字段默认以「原字段名。子字段名」命名(如 name.keyword
分析器配置 不同子字段可配置不同分析器(如中文分词、英文分词、不分词)
适用场景 同一字段需同时支持「全文检索 + 精准匹配」「分词查询 + 聚合排序」等场景

三、完整使用示例(商品名称多字段配置)

场景:商品名称需同时支持「全文检索」和「精准聚合」

1. 创建索引时显式定义多字段

json

复制代码
PUT /product_multi_field
{
  "mappings": {
    "properties": {
      "product_name": {  // 原始字段(主字段)
        "type": "text",  // 主类型:text,支持全文检索
        "analyzer": "ik_max_word",  // 中文分词器(需安装IK插件)
        "fields": {      // 多字段配置:为同一个值定义其他类型
          "keyword": {   // 子字段1:keyword类型,精准匹配
            "type": "keyword",
            "ignore_above": 256  // 超过256字符的部分忽略
          },
          "english": {   // 子字段2:text+英文分词器,适配英文名称
            "type": "text",
            "analyzer": "english"
          }
        }
      },
      "price": { "type": "float" }
    }
  }
}

配置说明

  • product_name(主字段):text 类型 + IK 分词,支持中文全文检索;
  • product_name.keywordkeyword 类型,支持精准匹配 / 聚合;
  • product_name.englishtext 类型 + 英文分词器,支持英文名称检索。
2. 写入数据(只需写原始字段)

json

复制代码
PUT /product_multi_field/_doc/1
{
  "product_name": "华为手机Pro 2024款",
  "price": 4999.0
}

PUT /product_multi_field/_doc/2
{
  "product_name": "iPhone 15 Pro Max",
  "price": 8999.0
}

关键 :写入时只需指定 product_name,ES 会自动为 product_name.keyword/product_name.english 生成对应索引,无需手动写入子字段。

3. 多字段的核心查询 / 聚合用法
场景 1:主字段全文检索(中文分词)

json

复制代码
GET /product_multi_field/_search
{
  "query": {
    "match": {
      "product_name": "华为手机"  // 匹配分词后的「华为」「手机」
    }
  }
}

结果:返回 product_name 为「华为手机 Pro 2024 款」的文档。

场景 2:子字段精准匹配(keyword)

json

复制代码
GET /product_multi_field/_search
{
  "query": {
    "term": {
      "product_name.keyword": "华为手机Pro 2024款"  // 精准匹配完整名称
    }
  }
}

结果:仅返回完全匹配该名称的文档(避免分词导致的模糊匹配)。

场景 3:子字段英文分词检索

json

复制代码
GET /product_multi_field/_search
{
  "query": {
    "match": {
      "product_name.english": "iphone pro"  // 英文分词后匹配
    }
  }
}

结果:返回 product_name 为「iPhone 15 Pro Max」的文档。

场景 4:子字段聚合(keyword)

json

复制代码
GET /product_multi_field/_search
{
  "size": 0,
  "aggs": {
    "group_by_product_name": {
      "terms": {
        "field": "product_name.keyword",  // 按完整名称精准分组
        "size": 10
      }
    }
  }
}

结果 :按「华为手机 Pro 2024 款」「iPhone 15 Pro Max」分别分组(若用主字段 product_name 聚合,会按分词后的单个词分组,结果无意义)。

4. 自动生成的多字段(ES 默认行为)

ES 对所有 text 类型字段,会自动生成一个 .keyword 子字段(无需显式定义),比如:

json

复制代码
// 仅定义text类型字段
PUT /test_index
{
  "mappings": {
    "properties": {
      "name": { "type": "text" }
    }
  }
}

// 写入数据后,可直接用 name.keyword 精准匹配
GET /test_index/_search
{
  "query": {
    "term": { "name.keyword": "张三" }
  }
}

这是 ES 最常用的多字段场景,也是新手容易忽略的点(比如之前你遇到的 hobbies.port.keyword 就是自动生成的)。

四、多字段的常见配置与限制

1. 新增多字段(索引已创建后)

可通过更新 mapping 为已有字段新增多字段(无需重建索引,但需重新索引数据才能生效):

json

复制代码
// 为product_name新增「拼音分词」子字段
PUT /product_multi_field/_mapping
{
  "properties": {
    "product_name": {
      "type": "text",
      "analyzer": "ik_max_word",
      "fields": {
        "keyword": { "type": "keyword", "ignore_above": 256 },
        "english": { "type": "text", "analyzer": "english" },
        "pinyin": {  // 新增拼音子字段(需安装拼音分词器)
          "type": "text",
          "analyzer": "pinyin_analyzer"
        }
      }
    }
  }
}

2. 核心限制

  • 多字段仅针对「同一个原始值」,无法为不同值配置不同子字段;
  • 子字段的类型需与主字段兼容(比如主字段是 text,子字段可设为 keyword/text,但不能设为 integer);
  • 新增多字段后,需重新索引历史数据(否则历史数据的子字段无索引,查询不到)。

五、适用场景总结

表格

场景 多字段配置方案
中文全文检索 + 精准匹配 / 聚合 主字段:text+IK 分词;子字段:keyword
英文名称检索 + 中文名称检索 主字段:text + 中文分词;子字段:text + 英文分词
日期字段(字符串)+ 排序 主字段:text;子字段:date
数值字段(字符串)+ 范围查询 主字段:text;子字段:integer/float

总结

  1. 单值多字段(Multi-fields)是让一个原始字段值同时支持多种索引方式的特性,核心解决「同一字段需满足不同查询 / 聚合需求」的问题;
  2. 最常用的配置是「text(主字段,全文检索)+ keyword(子字段,精准匹配 / 聚合)」,ES 会为 text 字段自动生成 .keyword 子字段;
  3. 多字段仅在索引层面生成副本,不额外存储原始数据,写入只需操作主字段,查询 / 聚合可指定子字段(格式:原字段名。子字段名)。

简单来说,多字段的核心价值是「一份数据,多种索引,适配多场景使用」,是 ES 处理复杂字段查询的必备技巧。

Elasticsearch Runtime 类型(Runtime Fields)详解

Runtime Fields(运行时字段)是 ES 7.11+ 引入的核心特性,简单来说:它是在查询 / 聚合时动态计算的字段,不存储在磁盘上,仅在内存中临时生成

可以把它理解为 ES 的「虚拟字段」------ 不用提前写入文档,也不用修改索引映射,就能基于现有字段动态生成新字段,解决传统静态映射的灵活性问题。


一、核心特点

  1. 无存储开销:不占用磁盘空间,数据仅在查询时计算,适合临时分析、数据修正场景。
  2. 无需重建索引:传统字段修改需要重建索引(耗时耗资源),Runtime 字段直接在查询时定义,立即生效。
  3. 灵活适配:支持基于现有字段做数据转换(如字符串转数字、时间格式修正、多字段拼接)。
  4. 支持多类型 :Runtime 字段支持 ES 所有基础类型(long/double/keyword/date/boolean 等)。

二、使用场景(新手最易理解的场景)

1. 临时修正数据格式

比如原始日志中「金额」字段是字符串("amount": "100.5"),想按数值聚合,不用重新导入数据,直接用 Runtime 转成 double

2. 多字段拼接 / 计算

比如现有 first_namelast_name,想临时生成 full_name 字段("full_name": "张三 李四")。

3. 兼容历史数据

老数据的时间字段格式不统一(有的是 yyyy-MM-dd,有的是 yyyy/MM/dd),用 Runtime 统一转成标准 date 类型。

4. 临时新增分析维度

比如基于 order_time(下单时间)动态生成 order_hour(下单小时)、order_weekday(下单星期),用于按小时 / 星期聚合。


三、使用方式(两种核心方式)

Runtime 字段有两种定义方式,新手优先掌握「查询时临时定义」,进阶再用「映射中预定义」。

方式 1:查询时临时定义(最常用,推荐新手)

search 请求中通过 runtime_mappings 定义,仅对本次查询生效。

示例 1:字符串转数值 原始文档:{"amount_str": "99.9", "product": "手机"}查询时把 amount_str 转成数值型 amount_num,并按数值聚合:

json

复制代码
GET /order_index/_search
{
  "runtime_mappings": {
    "amount_num": {  // 定义Runtime字段名
      "type": "double",  // 字段类型
      "script": {       // 核心:计算逻辑(Painless脚本)
        "source": "emit(Double.parseDouble(doc['amount_str'].value))"
      }
    }
  },
  "aggs": {
    "avg_amount": {  // 用Runtime字段做聚合
      "avg": {
        "field": "amount_num"
      }
    }
  },
  "fields": ["amount_str", "amount_num"]  // 返回Runtime字段
}
  • 关键语法:emit() 是 Painless 脚本的「输出函数」,把计算结果赋值给 Runtime 字段。
  • 效果:本次查询会临时生成 amount_num 字段,值为 99.9,可用于过滤、排序、聚合。

示例 2:动态生成日期维度 原始文档:{"order_time": "2026-03-21 14:30:00"}生成 order_hour(下单小时)和 order_weekday(星期几):

json

复制代码
GET /order_index/_search
{
  "runtime_mappings": {
    "order_hour": {
      "type": "integer",
      "script": {
        "source": "emit(LocalDateTime.parse(doc['order_time'].value, DateTimeFormatter.ofPattern('yyyy-MM-dd HH:mm:ss')).getHour())"
      }
    },
    "order_weekday": {
      "type": "keyword",
      "script": {
        "source": "def weekday = LocalDateTime.parse(doc['order_time'].value, DateTimeFormatter.ofPattern('yyyy-MM-dd HH:mm:ss')).getDayOfWeek(); emit(weekday.toString());"
      }
    }
  },
  "fields": ["order_time", "order_hour", "order_weekday"]
}

输出结果示例:

json

复制代码
"fields": {
  "order_time": ["2026-03-21 14:30:00"],
  "order_hour": [14],
  "order_weekday": ["SATURDAY"]
}
方式 2:映射中预定义(长期生效)

如果某个 Runtime 字段需要长期使用,可在索引映射中定义,后续所有查询都能直接使用:

json

复制代码
# 1. 创建索引时定义Runtime字段
PUT /order_index
{
  "mappings": {
    "runtime": {  // 预定义Runtime字段
      "amount_num": {
        "type": "double",
        "script": {
          "source": "emit(doc['amount_str'].value != null ? Double.parseDouble(doc['amount_str'].value) : 0)"
        }
      }
    },
    "properties": {  // 普通存储字段
      "amount_str": {"type": "keyword"},
      "product": {"type": "keyword"}
    }
  }
}

# 2. 后续查询可直接使用amount_num
GET /order_index/_search
{
  "aggs": {
    "avg_amount": {
      "avg": {"field": "amount_num"}
    }
  }
}

四、Runtime 字段 vs 普通字段(核心区别)

表格

特性 普通字段(Stored Fields) Runtime 字段(Runtime Fields)
存储方式 持久化到磁盘 仅查询时内存计算,不存储
索引重建 修改需重建索引 无需重建,立即生效
查询性能 快(直接读取磁盘) 稍慢(需实时计算)
适用场景 高频查询、核心业务字段 临时分析、数据修正、低频查询

五、新手注意事项

  1. 性能权衡:Runtime 字段会增加查询时的 CPU 开销(因为要实时计算),不建议用于高频、高并发的核心查询。
  2. 脚本限制 :计算逻辑基于 Painless 脚本,语法要符合 ES 规范(比如空值判断,避免 NullPointerException)。
  3. 版本要求:必须 ES 7.11+,Kibana 需同步版本才能在可视化中使用 Runtime 字段。
  4. 支持的操作 :Runtime 字段支持过滤、排序、聚合,但不支持全文检索(因为没有倒排索引)。

总结

  1. Runtime 字段是 ES 的「虚拟字段」:查询时动态计算,不存储、不占磁盘,无需重建索引。
  2. 核心价值是灵活性:解决静态映射的修改成本高、数据格式不统一等问题,适合临时分析 / 数据修正。
  3. 性能需权衡:查询时计算会增加 CPU 开销,优先用于低频分析场景,核心字段仍推荐用普通存储字段。

如果需要针对具体场景(比如日志分析、电商数据统计)写可直接运行的 Runtime 字段示例,可以告诉我,我帮你定制~

相关推荐
脱脱克克2 小时前
云端 OpenClaw 远程执行本地进程原理机制详解:Gateway、approvals 与 system.run 到底谁在判定、谁在执行?
linux·gateway·openclaw
青木川崎2 小时前
设计模式之面试题
java·开发语言·设计模式
空空潍2 小时前
Java核心基础语法:从原理到实战,夯实Java开发基石
java·开发语言
jing-ya2 小时前
day 57 图论part9
java·开发语言·数据结构·算法·图论
行者..................2 小时前
第2课:恢复出厂、掌握 Linux 基础命令并完成首次 GCC 编译
linux·qt·driver
huohuopro2 小时前
详解ThreadLocal的使用
java·开发语言·jvm
东离与糖宝2 小时前
微服务适配Java 26实战|GC优化+并发增强,线上稳了
java
专注API从业者2 小时前
淘宝商品详情 API 的 Webhook 回调机制设计与实现:实现数据主动推送
大数据·前端·数据结构·数据库