包含动态数据/ nested_objects的聚合

问题描述

我正在尝试汇总ElasticSearch中动态映射的字段。

例如:

POST test/_doc/1
{
    "settings": {
        "range": {
            "value": 200,"display": "200 km"
        },"transmitter": {
            "value": 1.2,"display": "1.2 Ghz"
        }
    }
}

settings下的属性是动态的。本质上,我需要这样的查询

{
    "size": 0,"query": {
        "match_all": {}
    },"aggs": {
        "settings": {
            "terms": {
                "field": "settings.*.display"
            }
        }
    }
}

由于*在这里不起作用,我想知道是否有一种方法可以从简单的脚本中返回字段,然后使用管道聚合?我在JavaScript中找不到与Object.keys(settings)相当的东西。

我已经看到了使用嵌套对象的方法,但是我想避免这种情况,因为与具有10000个属性nested_objects相比,可能有很多“设置”属性default limit是50。 >

解决方法

无痛的Object.keys()等同于.keySet()。您可以在脚本化指标agg中实现以下迭代逻辑:

GET test/_search
{
  "size": 0,"aggs": {
    "dynamic_fields_agg": {
      "scripted_metric": {
        "init_script": "state.map = [:];","map_script": """
          def source = params._source['settings'];
            for (def key : source.keySet()) {
              if (source[key].containsKey("display")) {
                 if (state.map.containsKey(key)) { 
                  state.map[key].add(source[key].display);
                 } else {
                   state.map[key] = [source[key].display];
                 }
              }
            }
        ""","combine_script": "return state","reduce_script": "return states"
      }
    }
  }
}

将会产生类似

{
  "aggregations":{
    "dynamic_fields_agg":{
      "value":[
        {
          "map":{
            "range":[
              "200 km"
            ],"transmitter":[
              "1.2 Ghz"
            ]
          }
        }
      ]
    }
  }
}

现在,您可以按自己的喜好对reduce / combine脚本中的值进行后处理。


在这里使用嵌套字段不会给您带来太多优势-那里也不允许使用通配符路径。我asked that前一段时间自己。


UPDATE-内联版本:

GET /test/_search
{  "size": 0,"aggs": {    "dynamic_fields_agg": {      "scripted_metric": {        "init_script": "state.map = [:];","map_script": "          def source = params._source[\"settings\"];\n            for (def key : source.keySet()) {\n              if (source[key].containsKey(\"display\")) {\n                 if (state.map.containsKey(key)) { \n                  state.map[key].add(source[key].display);\n                 } else {\n                   state.map[key] = [source[key].display];\n                 }\n              }\n            }","reduce_script": "return states"      }    }  }}

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...