Перебирайте предметы безболезненно, но «Поле не найдено» - PullRequest
1 голос
/ 31 октября 2019

Я пытаюсь сделать запрос выбора с помощью сценария 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 Ответ

2 голосов
/ 31 октября 2019

Это потому, что doc[<fieldName>] получает доступ к значениям документа, поэтому он не работает на вложенных структурах. Из документации Elasticsearch:

«Значения документа могут возвращать только« простые »значения поля, такие как числа, даты, географические точки, термины и т. Д., Или массивы этих значений, если поле многозначно. Он не может возвращать объекты JSON. "

Вам нужно поместить params._source[unitHolder] в переменную типа Map и посмотреть, содержит ли эта переменная unit.

Обновлено, включая пример:

Map unitHolderMap = params._source['unitHolder`];
if (unitHolderMap.containsKey('units')){
    // get the ages from their respective properties and evaluate them
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...