如何使用过滤器脚本在弹性搜索中迭代嵌套数组



我正在尝试在弹性搜索中筛选嵌套字段。嗯,我需要根据某些规则退回某些文件。为了重现我得到的错误,你可以参考这个例子:

PUT my-index-000001
{
"mappings": {
"properties": {
"user": {
"type": "nested" 
}
}
}
}
PUT my-index-000001/_doc/1
{
"group": "fans",
"user": [
{
"first": "John",
"last": "Smith"
},
{
"first": "Alice",
"last": "White"
}
]
}

可以看出,我们有一个对象数组(嵌套(。

我需要在嵌套字段上应用一个脚本,在那里我可以遍历用户数组。

例如,我尝试了这个:

GET my-index-000001/_search
{
"query": {
"nested": {
"path": "user",
"query": {
"bool": {
"filter": [
{
"script": {
"script": {
"inline": """
def users = doc['user'];
for ( int i = 0; i < users.size(); i++ ) {

}
return true;
"""
}
}
}
]
}
}
}
}
}

我收到这个错误

{
...
"script_stack" : [
"org.elasticsearch.search.lookup.LeafDocLookup.get(LeafDocLookup.java:90)",
"org.elasticsearch.search.lookup.LeafDocLookup.get(LeafDocLookup.java:41)",
"users = doc['user'];n                  ",
"            ^---- HERE"
],
...
"caused_by" : {
"type" : "illegal_argument_exception",
"reason" : "No field found for [user] in mapping with types []"
}
}
}
]
},
"hits" : {
"total" : {
"value" : 0,
"relation" : "eq"
},
"max_score" : null,
"hits" : [ ]
}
}

Elasticsearch 7.7版

这样做可能吗?我已经复习了一些答案,但我不清楚。

嵌套文档功能强大,因为您保留了某些属性连接,但也有无法迭代的缺点,如本文所述。


话虽如此,您可以使用copy_to来压平users属性这样的功能:

PUT my-index-000001
{
"mappings": {
"properties": {
"user__first_flattened": {
"type": "keyword"
},
"user": {
"type": "nested",
"properties": {
"first": {
"type": "keyword",
"copy_to": "user__first_flattened"
}
}
}
}
}
}

然后

PUT my-index-000001/_doc/1
{
"group": "fans",
"user": [
{
"first": "John",
"last": "Smith"
},
{
"first": "Alice",
"last": "White"
}
]
}

现在,您可以访问字段值并对其进行迭代(如果需要,还可以使用循环索引来帮助定位/识别正确的"嵌套"子文档

GET my-index-000001/_search
{
"query": {
"bool": {
"filter": [
{
"script": {
"script": {
"inline": """
def users = doc.user__first_flattened;
// users == [Alice, John]
for ( int i = 0; i < users.size(); i++ ) {

}
return true;
"""
}
}
}
]
}
}
}

请注意,我们不再执行nested查询b/c,因为我们不在该上下文中,并且在根中获得了可用的扁平字段。


还值得一提的是,您可以用include_in_root替换copy_to,这在这里同样有用。

给定父文档的嵌套文档列表在嵌套上下文中不可用。因此,"doc['user']'在脚本中为您提供了异常。但是,可以按以下方式访问单个嵌套文档:

GET my-index-000001/_search
{
"query": {
"nested": {
"path": "user",
"query": {
"script": {
"script": "doc['user.first.keyword']=='John'" // <==== This can be done.
}
}
}
}
}

最新更新