使用字段 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 的返回类型 |
||
---|---|---|---|---|
|
|
|
|
|
|
|
- |
|
|
|
|
- |
|
|
|
|
- |
|
|
|
|
- |
|
|
|
|
- |
|
|
|
|
- |
|
|
|
|
- |
|
|
|
|
- |
|
|
|
|
- |
|
|
|
|
- |
|
|
|
|
|
|
|
|
|
- |
|
|
|
|
- |
|
|
|
|
|
|
|
|
|
- |
|
|
|
|
- |
|
|
|
|
|
|
|
|
|
- |
|
|
|
|
- |
|
|
|
|
- |
|
|
|
|
- |
|
|