使用字段 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 |
||
|---|---|---|---|---|
|
|
|
|
|
|
|
- |
|
|
|
|
- |
|
|
|
|
- |
|
|
|
|
- |
|
|
|
|
- |
|
|
|
|
- |
|
|
|
|
- |
|
|
|
|
- |
|
|
|
|
- |
|
|
|
|
- |
|
|
|
|
|
|
|
|
|
- |
|
|
|
|
- |
|
|
|
|
|
|
|
|
|
- |
|
|
|
|
- |
|
|
|
|
|
|
|
|
|
- |
|
|
|
|
- |
|
|
|
|
- |
|
|
|
|
- |
|
|