elasticsearch通过具有变量嵌套的嵌套字段聚合(或在特定json字段上聚合)

x9ybnkn6  于 2021-06-10  发布在  ElasticSearch
关注(0)|答案(1)|浏览(391)

我有以下结构 GET /index-*/_mapping :

"top_field" : {
      "properties" : {
        "dict_key1" : {
          "properties" : {
            "field1" : {...},
            "field2" : {...},
            "field3" : {
              "type" : "text",
              "fields" : {
                "keyword" : {
                  "type" : "keyword",
                  "ignore_above" : 256
                }
              }
            },
            "field4" : {...}
          },
        "dict_key2" : {
          "properties" : {
            "field1" : {...},
            "field2" : {...},
            "field3" : {
              "type" : "text",
              "fields" : {
                "keyword" : {
                  "type" : "keyword",
                  "ignore_above" : 256
                }
              }
            },
            "field4" : {...}
          },
        "dict_key3": ...
        }

换句话说, top_field 存储json。
我想把这些加起来 'field3.keyword' 不管 dict_key* . 像这样的 top_field.*.field3.keyword .
但是,无论是否使用嵌套的术语聚合,我都无法让它工作。我也试着用不同的 dict_key* ,那也差不多,但我也没法让它工作。
我该怎么做?

kq4fsx7k

kq4fsx7k1#

热释光;dr i不久前也遇到了同样的问题(用嵌套通配符路径表示聚合),结果发现由于执行查找和路径访问器的方式,这是不可能的。
不过,有一个脚本化的解决方法:

{
  "size": 0,
  "aggs": {
    "terms_emulator": {
      "scripted_metric": {
        "init_script": "state.keyword_counts = [:]",
        "map_script": """
          def source = params._source['top_field'];
          for (def key : source.keySet()) {
            if (!source[key].containsKey('field3')) continue;

            def field3_kw = source[key]['field3'];

            if (state.keyword_counts.containsKey(field3_kw)) { 
              state.keyword_counts[field3_kw] += 1;
            } else {
              state.keyword_counts[field3_kw] = 1;
            }
          }
        """,
        "combine_script": "state",
        "reduce_script": "states[0]"
      }
    }
  }
}

使某物沿着

"aggregations" : {
  "terms_emulator" : {
    "value" : {
      "keyword_counts" : {
        "world" : 1,
        "hello" : 2
      }
    }
  }
}

虽然这很管用,但我不建议在生产中使用脚本。您可以重新构造数据,以便可以进行直接的查找。例如:

{
  "top_field": {
    "entries": [
      {
        "group_name": "dict_key1",
        "key_value_pairs": {
          "field3": "hello"
        }
      },
      {
        "group_name": "dict_key2",
        "key_value_pairs": {
          "field3": "world"
        }
      }
    ]
  }
}

使 entries 嵌套的。甚至可能是沟 top_field 因为它看起来是多余的,直接从 entries .

相关问题