首页/数据/NoSQL 速查/runtime fields 运行时字段
Elasticsearch89 条

runtime fields 运行时字段

runtime 字段在查询时计算、不占索引空间,可在查询请求里临时定义,也可写进索引映射长期生效;适合对已有数据做探索性统计而不重建索引。

NoSQL 速查数据更新于 2026-10-13

runtime 字段是什么

runtime 字段在查询时计算,不占索引空间:既可以在查询请求里用 runtime_mappings 临时定义,也可以写进索引映射长期生效。它适合对已有数据做探索性统计,比如从复合字段里拆出值、按时间派生星期与时段、给旧索引补一个原本没有的字段,而不用先重建索引。

能用的同时要算成本

runtime 字段可以被搜索、聚合与排序,行为与普通字段一致,前提是脚本输出的类型与声明的 type 匹配。代价是每次查询都按需计算:命中量大或把它当常用过滤条件时,成本会持续发生。统计口径确认稳定后,应该把它固化进映射或直接物化成真实字段。

基本信息

定义位置查询请求的 runtime_mappings,或映射里的 runtime 段
常见类型keyword、long、double、date 等
输出方式脚本里用 emit() 输出值
典型用途拆复合字段、派生时间维度、给旧索引补字段
适用版本Elasticsearch 7.11 起提供

示例

示例
GET /logs/_search
{
  "size": 0,
  "runtime_mappings": {
    "day_of_week": {
      "type": "keyword",
      "script": { "source": "emit(doc['@timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT))" }
    }
  },
  "aggs": { "by_day": { "terms": { "field": "day_of_week" } } }
}

# 固化到映射:之后所有查询都能直接用这个字段
PUT /logs/_mapping
{ "runtime": { "day_of_week": { "type": "keyword", "script": { "source": "emit(doc['@timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT))" } } } }

典型使用场景

  • 探索性统计:不重建索引就试算新维度
  • 拆字段:把组合值拆成可聚合的独立维度
  • 时间派生:从时间戳算出星期、小时段、是否工作日
  • 旧索引补字段:历史数据无法回填时用 runtime 顶替
  • 灰度验证:先确认口径正确,再决定是否物化成真实字段

要素与注意

要素含义注意
runtime_mappings请求级定义,只对本次查询生效适合临时探索
映射 runtime 段长期生效,所有查询可见改动后对后续查询立即生效
emit()脚本输出值的入口类型与声明不符会丢值
type字段类型决定能否聚合、排序以及按什么方式比较
脚本类型与 emit 输出不匹配会静默丢值,聚合前先用简单查询验证字段确实有输出,再上聚合,避免对着一堆空桶排查。
把 runtime 字段当常用过滤条件会持续承担计算成本,高频使用的字段应常规索引;在大量文档上跑复杂脚本会明显拖慢查询。

易错点

  • 脚本类型与 emit 输出不匹配会静默丢值,出现空桶时先验证字段输出再怀疑数据
  • 把 runtime 字段当高频过滤条件会持续付出计算成本,口径稳定后应物化为真实字段
  • runtime 字段无法参与索引层面的排序优化,大结果集排序时性能明显差于索引字段
  • 脚本里引用不存在的原始字段不会报错,只会得到空值,调试时先确认字段名与映射

数据来源与参考

  • Elasticsearch Guide: Runtime fields
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌