在脚本度量标准聚合中访问_aggs元素时获取null_pointer_exception

时间:2017-12-07 01:41:16

标签: elasticsearch elasticsearch-painless

我有一个每秒的股票价格指数,如下所示,我试图将它们聚合成5分钟的更大的价格。使用min / max可以轻松聚合高低。然而,开放和关闭更难。我正在尝试使用脚本度量标准聚合,但我得到一个无法解释的空指针异常。

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

我的查询如下所示,虽然我已经从combine_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]"
                    }
                }
            }
        }
    }
}

如果我运行查询,您可以看到它输出一个Map(按键时间和打开),为您所期望的“打开”值。

{
  "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中做一些额外的事情,但是如果没有获得NPE,似乎无法访问_aggs中任何地图的属性。

1 个答案:

答案 0 :(得分:1)

我能够使用?.运算符解决问题。我猜是因为我有一些空字段,它试图访问null上的属性而爆炸。所以通过添加它,我得到了我的期望。所以这只是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
          }
        }
      ]
    }
  }
}