使用字段 API 访问文档中的字段
编辑使用 field
API 访问文档中的字段编辑
field
API 仍在开发中,应视为测试功能。该 API 可能会发生变化,并且此迭代可能不是最终状态。有关功能状态,请参阅 #78920。
使用 field
API 访问文档字段
field('my_field').get(<default_value>)
此 API 从根本上改变了您在 Painless 中访问文档的方式。以前,您必须使用要访问的字段名称访问 doc
映射
doc['my_field'].value
以这种方式访问文档字段无法处理缺失值或缺失映射,这意味着要编写健壮的 Painless 脚本,您需要包含逻辑来检查字段和值是否存在。
相反,请使用 field
API,这是在 Painless 中访问文档的首选方法。field
API 处理缺失值,并将演变为抽象访问 _source
和 doc_values
。
某些字段尚与 fields
API 不兼容,例如 text
或 geo
字段。继续使用 doc
访问 field
API 不支持的字段类型。
field
API 返回一个 Field
对象,该对象使用多个值迭代字段,并通过 get(<default_value>)
方法提供对底层值的访问,以及类型转换和辅助方法。
field
API 返回您指定的默认值,而不管该字段是否存在或当前文档是否有任何值。这意味着 field
API 可以处理缺失值,而无需额外的逻辑。对于引用类型(例如 keyword
),默认值可以是 null
。对于基元类型(例如 boolean
或 long
),默认值必须是匹配的基元类型,例如 false
或 1
。
方便、更简单的访问编辑
您可以包含 $
快捷方式,而不是使用 get()
方法显式调用 field
API。只需包含 $
符号、字段名称和默认值(以防字段没有值)
$(‘field’, <default_value>)
借助这些增强的功能和简化的语法,您可以编写更短、更简单、更易于阅读的脚本。例如,以下脚本使用过时的语法来确定索引文档中两个复杂 datetime
值之间的毫秒差
if (doc.containsKey('start') && doc.containsKey('end')) { if (doc['start'].size() > 0 && doc['end'].size() > 0) { ZonedDateTime start = doc['start'].value; ZonedDateTime end = doc['end'].value; return ChronoUnit.MILLIS.between(start, end); } else { return -1; } } else { return -1; }
使用 field
API,您可以更简洁地编写相同的脚本,而无需额外的逻辑来确定在对字段进行操作之前字段是否存在
ZonedDateTime start = field('start').get(null); ZonedDateTime end = field('end').get(null); return start == null || end == null ? -1 : ChronoUnit.MILLIS.between(start, end)
支持的映射字段类型编辑
下表列出了 field
API 支持的映射字段类型。对于每个受支持的类型,列出了由 field
API(来自 get
和 as<Type>
方法)和 doc
映射(来自 getValue
和 get
方法)返回的值。
fields
API 当前不支持某些字段,但您仍然可以通过 doc
映射访问这些字段。有关受支持字段的最新列表,请参阅 #79105。
映射字段类型 | 从 field 返回的类型 |
从 doc 返回的类型 |
||
---|---|---|---|---|
|
|
|
|
|
|
|
- |
|
|
|
|
- |
|
|
|
|
- |
|
|
|
|
- |
|
|
|
|
- |
|
|
|
|
- |
|
|
|
|
- |
|
|
|
|
- |
|
|
|
|
- |
|
|
|
|
- |
|
|
|
|
|
|
|
|
|
- |
|
|
|
|
- |
|
|
|
|
|
|
|
|
|
- |
|
|
|
|
- |
|
|
|
|
|
|
|
|
|
- |
|
|
|
|
- |
|
|
|
|
- |
|
|
|
|
- |
|
|