映射运行时字段编辑

您可以通过在映射定义下添加一个 runtime 部分并定义 Painless 脚本 来映射运行时字段。此脚本可以访问文档的整个上下文,包括通过 params._source 的原始 _source 以及任何映射字段及其值。在查询时,脚本运行并为查询所需的每个脚本字段生成值。

例如,以下请求中的脚本从定义为 date 类型的 @timestamp 字段计算星期几。该脚本根据 timestamp 的值计算星期几,并使用 emit 返回计算出的值。

response = client.indices.create(
  index: 'my-index-000001',
  body: {
    mappings: {
      runtime: {
        day_of_week: {
          type: 'keyword',
          script: {
            source: "emit(doc['@timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT))"
          }
        }
      },
      properties: {
        "@timestamp": {
          type: 'date'
        }
      }
    }
  }
)
puts response
PUT my-index-000001/
{
  "mappings": {
    "runtime": {
      "day_of_week": {
        "type": "keyword",
        "script": {
          "source": "emit(doc['@timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT))"
        }
      }
    },
    "properties": {
      "@timestamp": {"type": "date"}
    }
  }
}

runtime 部分可以是以下任何数据类型

  • 布尔值
  • 复合
  • 日期
  • 双精度
  • 地理点
  • IP
  • 关键字
  • 长整型
  • 查找

类型为 date 的运行时字段可以接受 format 参数,与 date 字段类型完全相同。

类型为 lookup 的运行时字段允许从相关索引中检索字段。请参阅 从相关索引中检索字段

如果 动态字段映射 启用,其中 dynamic 参数设置为 runtime,则新字段会自动作为运行时字段添加到索引映射中

response = client.indices.create(
  index: 'my-index-000001',
  body: {
    mappings: {
      dynamic: 'runtime',
      properties: {
        "@timestamp": {
          type: 'date'
        }
      }
    }
  }
)
puts response
PUT my-index-000001
{
  "mappings": {
    "dynamic": "runtime",
    "properties": {
      "@timestamp": {
        "type": "date"
      }
    }
  }
}

在没有脚本的情况下定义运行时字段编辑

运行时字段通常包含一个以某种方式操作数据的 Painless 脚本。但是,在某些情况下,您可能需要定义一个没有脚本的运行时字段。例如,如果您想从 _source 中检索单个字段而不进行更改,则不需要脚本。您可以只创建一个没有脚本的运行时字段,例如 day_of_week

response = client.indices.create(
  index: 'my-index-000001',
  body: {
    mappings: {
      runtime: {
        day_of_week: {
          type: 'keyword'
        }
      }
    }
  }
)
puts response
PUT my-index-000001/
{
  "mappings": {
    "runtime": {
      "day_of_week": {
        "type": "keyword"
      }
    }
  }
}

如果没有提供脚本,Elasticsearch 会在查询时隐式地在 _source 中查找与运行时字段同名的字段,如果存在则返回一个值。如果不存在同名的字段,则响应不包含该运行时字段的任何值。

在大多数情况下,请尽可能通过 doc_values 检索字段值。使用运行时字段访问 doc_values 比从 _source 检索值更快,因为数据是从 Lucene 加载的。

但是,在某些情况下,需要从 _source 检索字段。例如,text 字段默认情况下没有 doc_values,因此您必须从 _source 中检索值。在其他情况下,您可能选择在特定字段上禁用 doc_values

或者,您可以使用 params._source 前缀您要检索值的字段(例如 params._source.day_of_week)。为了简单起见,建议尽可能在映射定义中定义没有脚本的运行时字段。

忽略运行时字段上的脚本错误编辑

脚本在运行时可能会抛出错误,例如在访问文档中的缺失或无效值或执行无效操作时。可以使用 on_script_error 参数来控制发生这种情况时的错误行为。将此参数设置为 continue 将会静默忽略此运行时字段上的所有错误。默认的 fail 值将导致分片失败,并在搜索响应中报告。

更新和删除运行时字段编辑

您可以随时更新或删除运行时字段。要替换现有的运行时字段,请在映射中添加一个同名的新的运行时字段。要从映射中删除运行时字段,请将运行时字段的值设置为 null

response = client.indices.put_mapping(
  index: 'my-index-000001',
  body: {
    runtime: {
      day_of_week: nil
    }
  }
)
puts response
PUT my-index-000001/_mapping
{
 "runtime": {
   "day_of_week": null
 }
}