【问题标题】:ElasticSearch/Painless: How do I access/sum all values in an objectElasticSearch/Painless:如何访问/汇总对象中的所有值
【发布时间】:2017-05-10 19:54:33
【问题描述】:

我一直在研究聚合,以及使用 painless 编写脚本,但我无法弄清楚如何对对象中的所有值进行迭代/求和。

例子:

我的映射看起来像

"field1": {
  "properties": {
    "subfield1": {
      "type": "float"
    },
    "subfield2": {
      "type": "float"
    },
    "subfield3": {
      "type": "float"
    }
  }
}

假设我的数据如下所示:

{
  "field1" : {
    "subfield1": 50.0,
    "subfield2": 20.5,
    "subfield3": 30.5
  }
}

我想对50.0 + 20.5 + 30.5 执行范围查询,或者基本上以某种方式访问​​field1 对象中的所有值。

聚合不允许我在字段中使用通配符。 我是looking at the code for LeafDocLookup(内部用于无痛),我看到相关方法被禁用了。

我已经设法编写了这样的脚本:

"query": {
  "script": {
    "script": {
      "inline": "return (doc['field1.subfield1'].value + doc['field1.subfield2'].value + doc['field1.subfield3'].value > 50);",
      "lang": "painless"
    }
  }
}

但这显然是次优的,并没有解决动态键的主要问题。

【问题讨论】:

  • 创建或更新文档时能否存储子键的总数(即总和)?然后,您只需查询一个字段,而不必担心动态键名。
  • 我可以,但我确信还有更多用例需要访问哈希图的所有元素。这不正是我们有keySet()values() 这样的方法的原因吗?
  • Painless 可能支持获取一个字段的所有子对象,但总的来说我建议不要在 ES 查询中使用脚本。它们很慢,通常有更好的方法来查询或存储文档以避免脚本。

标签: java json elasticsearch kibana elasticsearch-painless


【解决方案1】:

我终于明白了!它在 elasticsearch 中的 doc 对象中不可用,但在 _ctx.source 可用。

所以,如果我使用 params['_source'],我可以将对象作为 Java HashMap 对象访问

"query": {
  "script": {
    "script": {
      "inline": "float sum = 0.0f; for (float v: params['_source'].values()) { sum += v; } return (sum > 50);",
      "lang": "painless"
    }
  }
}

【讨论】:

  • 不错,+1。我正在使用它来查找具有超过给定数量的数组条目的所有属性,如"params['_source'].keySet().size() > 990"
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-13
  • 1970-01-01
相关资源
最近更新 更多