我需要为我的查询迭代无痛脚本字段上的嵌套对象,但符号 doc['nestedProperty.property'] 没有给我值,也没有使用数组符号 doc['nestedProperty.property'][0]
关于如何使用它的任何想法?
一个文档示例:
{
"neestedProperty": [
{
"property": 12,
"innerNeestedProperty": {
"innerProperty1": 45,
"innerProperty2": -45
}
}
]
}
Run Code Online (Sandbox Code Playgroud)
示例查询:
{
"query": {
match_all: {}
},
"script_fields": {
"scripted": {
"script": {
"inline": "doc['neestedProperty.property'] * params.multiplier",
"params": {
"multiplier": 100
},
"lang": "painless"
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
该doc-notation显然不嵌套对象上的工作,但你可以直接访问_source的霍斯特Seirer指出-object。
复杂的是访问_source取决于执行脚本的上下文;-ctx变量并不总是可用。对于scripted_fields,您可以改为使用params._source. 但这在其他上下文中不可用(例如在查询部分)
有了 之后_source,可以使用get或点符号来访问元素,并且嵌套的字段将是一个数组。因此,例如params._source.nestedProperty[0].property将从第一个嵌套对象中获取值。
对于脚本化字段,您应该返回一个对象,但它可以是一个数组。所以在你的例子中,我会使用这样的东西:
def returnval=[];
for (nested in params._source.nestedProperty) {
returnval.add(nested['property']*params.multiplier)
}
return returnval;
Run Code Online (Sandbox Code Playgroud)
即使您将源作为参数调用,也不必将其添加到参数列表中。
如果您需要从父文档的角度编写脚本(也许您需要组合多个嵌套文档),则上述内容很有用。
但是,有一个缺点是您只能使用原始源,这意味着未分析的字符串和只是字符串的日期等。
通常,通过包含script_fields在一个inner_hits部分中,直接在嵌套文档上使用脚本化字段可能会容易得多。像这样:
{
"query": {
"nested": {
"path": "nestedProperty",
"query": {
"match_all": {}
},
"inner_hits": {
"_source": true,
"script_fields": {
"my_value": {
"script": {
"source": "doc['nestedProperty.property'].value*params.multiplier",
"params": {
"multiplier": 100
}
}
}
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
此代码所做的只是单独查看每个嵌套文档(因为它们在内部存储为单独的文档),并在其上运行脚本。而这些(内部单独存储的)文档可以使用 doc-notation。
结果将为您提供原始文档,以及一个inner_hits包含每个嵌套文档及其来源的部分,以及一个脚本字段my_value。
使用嵌套文档作为单独的条目可能只是感觉很奇怪,但仍然必须使用完整路径 ( nestedProperty.property)
并且您必须注意这样一个事实,即这个查询现在只返回其中包含嵌套文档的文档,而之前的代码将返回带有作为脚本字段的空数组的文档。但是,如果您想要所有文档,您可以使用带有match_all-clause的 bool-query 。
最后,我不知道这是否适用于 elastic 5(就像最初的问题一样),但我已经在 7.3 上进行了确认,并且根据文档,它也应该适用于例如 5.0。
我知道我迟到了,但也许我可以帮助其他人寻找相同的答案。
Hor*_*rer -1
_source对象实际上是一个LinkedHashMap(请参阅参考文档中有关无痛调试的章节。)因此,为了访问字段,您可以使用get方法。如果您需要通过参数动态选择文档字段,这会很方便。
选择字段的另一种方法是使用点语法:
ctx._source.some_field
Run Code Online (Sandbox Code Playgroud)
导航和选择文档字段时,您必须记住字段的数据类型。
对于您的特定情况,neestedProperty字段是您可以迭代的嵌套类型的列表(/ ArrayList )。该列表的元素的类型为LinkedHashMap。
因此,对于您的示例,这将是:
ArrayList nestedObjects = ctx._source.get('neestedProperty');
for(o IN nestedObjects) {
o.get('property') = o.get('property')*params.multiplier;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6169 次 |
| 最近记录: |