使用字段 API 访问文档中的字段
edit使用field
API访问文档中的字段
editThe 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 不支持的字段类型。
The field
API 返回一个 Field
对象,该对象迭代具有多个值的字段,通过 get(
方法提供对底层值的访问,以及类型转换和辅助方法。
无论字段是否存在或当前文档是否有任何值,field
API 都会返回您指定的默认值。
这意味着 field
API 可以在不需要额外逻辑的情况下处理缺失值。对于 keyword
这样的引用类型,默认值可以是 null
。对于 boolean
或 long
这样的原始类型,默认值必须是匹配的原始类型,例如 false
或 1
。
便捷,更简单的访问
edit不需要显式调用带有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)
支持的映射字段类型
edit下表列出了field
API支持的映射字段类型。对于每种支持的类型,列出了field
API(来自get
和as
方法)以及doc
映射(来自getValue
和get
方法)返回的值。
目前,fields
API 不支持某些字段,但您仍然可以通过 doc
映射访问这些字段。有关支持字段的最新列表,请参阅 #79105。
Mapped field type | Returned type from field |
Returned type from doc |
||
---|---|---|---|---|
|
|
|
|
|
|
|
- |
|
|
|
|
- |
|
|
|
|
- |
|
|
|
|
- |
|
|
|
|
- |
|
|
|
|
- |
|
|
|
|
- |
|
|
|
|
- |
|
|
|
|
- |
|
|
|
|
- |
|
|
|
|
|
|
|
|
|
- |
|
|
|
|
- |
|
|
|
|
|
|
|
|
|
- |
|
|
|
|
- |
|
|
|
|
|
|
|
|
|
- |
|
|
|
|
- |
|
|
|
|
- |
|
|
|
|
- |
|
|