Получение null_pointer_exception при доступе к элементам _aggs в агрегировании метрик по сценарию

У меня есть индекс биржевых тиков за каждую секунду, который выглядит следующим образом, и я пытаюсь объединить их в более крупные тики по 5 минут. Агрегировать максимум и минимум легко, используя мин/макс. Однако открытие и закрытие сложнее. Я пытаюсь использовать агрегирование метрик по сценарию, но получаю исключение нулевого указателя, которое не могу объяснить.

{ "time": "2017-12-06 12:02:00", "high": 10, "low": 1, "open": 1, "close": 5}

Мой запрос выглядит следующим образом, хотя я многое удалил из comb_script и reduce_script, чтобы его было легко читать.

{
    "size": 0,
    "aggs": {
        "ticks": {
            "date_histogram": {
                "field":"time",
                "interval":"5m"
            },
            "aggs": {
                "open": {
                    "scripted_metric": {
                        "init_script": "params._agg.opens = []",
                        "map_script": "params._agg.opens.add(['time': doc.time.value.getMillis(),'open':doc.open.value])",
                        "combine_script": "return params._agg.opens[0]",
                        "reduce_script":  "return params._aggs[0]"
                    }
                }
            }
        }
    }
}

Если я запущу запрос, вы увидите, что он выводит карту (с ключами time и open) для значения «open», как и следовало ожидать.

{
  "aggregations": {
    "ticks": {
      "buckets": [
        {
          "key_as_string": "2017-12-06 14:20",
          "key": 1512570000000,
          "doc_count": 6,
          "volume": {
            "value": 84.09597664
          },
          "high": {
            "value": 12886
          },
          "low": {
            "value": 12874.99
          },
          "open": {
            "value": {
              "time": 1512570420000,
              "open": 12874.99
            }
          }
        }
      ]
    }
  }
}

Но если я попытаюсь получить доступ к любым свойствам карты (в качестве простого примера, просто возвращающего params._aggs[0]['open']), я получаю исключение нулевого указателя. Я пытался получить к нему доступ с помощью params._aggs[0].open и даже установить его на карту, а затем получить доступ к этой карте Map myMap = params._aggs[0]; return myMap['open'];, но получаю ту же ошибку.

{
  "error": {
    "root_cause": [],
    "type": "search_phase_execution_exception",
    "reason": "",
    "phase": "fetch",
    "grouped": true,
    "failed_shards": [],
    "caused_by": {
      "type": "script_exception",
      "reason": "runtime error",
      "script_stack": [
        "return params._aggs[0]['open']",
        "                   ^---- HERE"
      ],
      "script": "return params._aggs[0]['open']",
      "lang": "painless",
      "caused_by": {
        "type": "null_pointer_exception",
        "reason": null
      }
    }
  },
  "status": 503
}

Это проблема, потому что мне нужно сделать некоторые дополнительные вещи в reduce_script, но я не могу получить доступ к каким-либо свойствам карт в _aggs без получения NPE.


person dustins    schedule 07.12.2017    source источник
comment
проблема, кажется, _aggs против _agg. Вы создаете _agg, но пытаетесь получить доступ к _aggs   -  person Val    schedule 07.12.2017
comment
Спасибо @Val, но я не думаю, что это так, потому что это работает, пока я не попытаюсь получить доступ к свойству на _aggs[0]. Точно так же они показывают это в своих документах (elastic.co/guide/en/elasticsearch/reference/current/). Я думаю, это потому, что _agg — это совокупность осколков, а _aggs — это комбинация всех _agg.   -  person dustins    schedule 07.12.2017
comment
Доооо! Что произойдет, если вы просто вернете params._aggs или полностью исключите reduce_script?   -  person Val    schedule 07.12.2017


Ответы (1)


Я смог решить проблему с помощью оператора ?.. Я предполагаю, что из-за того, что у меня были нулевые поля, он взрывался при попытке доступа к свойствам с нулевым значением. Так что, просто добавив это, я получаю то, что ожидаю. Так что это просто вопрос params._aggs[0] ?. open

{
    "size": 0,
    "aggs": {
        "ticks": {
            "date_histogram": {
                "field":"time",
                "interval":"5m"
            },
            "aggs": {
                "open": {
                    "scripted_metric": {
                        "init_script": "params._agg.opens= []",
                        "map_script": "params._agg.opens.add(['time': doc.time.value.getMillis(),'open':doc.open.value])",
                        "combine_script": "return params._agg.opens[0]",
                        "reduce_script":  "return params._aggs[0]?.open"
                    }
                }
            }
        }
    }
}
{
  "aggregations": {
    "ticks": {
      "buckets": [
        {
          "key_as_string": "2017-12-07 12:20",
          "key": 1512649200000,
          "doc_count": 2,
          "open": {
            "value": 13
          }
        }
      ]
    }
  }
}
person dustins    schedule 07.12.2017