轻松地遍历所有项目,但“找不到字段”

时间:2019-10-31 12:40:09

标签: elasticsearch elasticsearch-painless

我正在尝试使用无痛脚本进行选择查询,但是在响应中我不断收到错误消息,指出该脚本无效。

在这个简化的脚本中,我要检查的是,给定的参数年龄是否都等于'unit.info'中的年龄。

错误:

    "if(containsAge(doc['unitHolder.units'], params.ages)){",
    "                   ^---- HERE",...
"caused_by": {
      "type": "illegal_argument_exception",
      "reason": "No field found for [unitHolder.units] in mapping with types [pack]"
      }

请求查询:

    {
        "query": {
            "bool": {
                "must": [
                    {
                        "script": {
                            "script": {
                                "source": "boolean containsAge(def unit, def ages) 
                                {
                                    if(unit.info.children.minAge != null)
                                    {
                                        int nrAdults = 0;
                                        int nrChildren = 0;
                                        int nrInfants = 0;

                                        for (age in ages)
                                        {
                                            if (age < unit.info.children.maxAge.value)
                                            {
                                                nrAdults++;
                                            }else if(age > unit.info.children.minAge.value)
                                            {
                                                nrInfants++;
                                            }else{
                                                nrChildren++;
                                            }
                                        }
                                        if (nrAdults > 2)
                                        {
                                            return true;
                                        }
                                    }
                                    return false;
                                }
                                if(containsAge(doc['unitHolder.units'], params.ages))
                                {
                                    return true;
                                }
                                return false;",
                                "lang": "painless",
                                "params": {
                                    "ages": [
                                        50,
                                        35
                                    ]
                                }
                            }
                        }
                    }
                ]
            }
        },
        "size": 10
    }

映射:

"mappings": {
    "pack": {
        "properties": {
            "unitHolder": {
                "properties": {
                    "createDate": {
                        "type": "date"
                    },
                    "units": {
                        "properties": {
                            "info": {
                                "properties": {
                                    "children": {
                                        "properties": {
                                            "maxAge": {
                                                "type": "long"
                                            },
                                            "minAge": {
                                                "type": "long"
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

1 个答案:

答案 0 :(得分:2)

这是因为doc[<fieldName>]访问文档值,因此它不适用于嵌套结构。从Elasticsearch文档中:

  

“文档值只能返回“简单”字段值,例如数字,日期,地理位置,术语等,或者如果这些字段是多值的,则返回这些值的数组。它不能返回JSON对象。” < / p>

您需要的是将params._source[unitHolder]放入Map型变量中,然后查看该变量是否包含unit

已更新为包括一些示例:

Map unitHolderMap = params._source['unitHolder`];
if (unitHolderMap.containsKey('units')){
    // get the ages from their respective properties and evaluate them
}