Elasticsearch - 组合来自多个文档的字段

Gra*_*ham 3 arrays merge aggregate elasticsearch

假设我有一堆这样的文件:

{
    "foo" : [1, 2, 3]
}

{
    "foo" : [3, 4, 5]
}
Run Code Online (Sandbox Code Playgroud)

对于针对这些文档运行的查询,我正在寻找一种方法来返回所有值的数组foo(理想情况下是唯一值,但可以重复):

{
    "foo" : [1, 2, 3, 3, 4, 5]
}
Run Code Online (Sandbox Code Playgroud)

我已经研究了聚合 API,但如果可能的话,我看不出如何实现这一点。我当然可以在代码中手动编译结果,但是我可以拥有数千个文档,以这种方式获得结果会更清晰。

Oca*_*tal 5

您可以使用带有reduce_script 的脚本化指标聚合

设置一些测试数据:

curl -XPUT http://localhost:9200/testing/foo/1 -d '{ "foo" : [1, 2, 3] }'
curl -XPUT http://localhost:9200/testing/foo/2 -d '{ "foo" : [4, 5, 6] }'
Run Code Online (Sandbox Code Playgroud)

现在试试这个聚合:

curl -XGET "http://localhost:9200/testing/foo/_search" -d'
{
  "size": 0,
  "aggs": {
    "fooreduced": {
      "scripted_metric": {
        "init_script": "_agg[\"result\"] = []",
        "map_script":  "_agg.result.add(doc[\"foo\"].values)",
        "reduce_script": "reduced = []; for (a in _aggs) { for (entry in a) { word = entry.key; reduced += entry.value } }; return reduced.flatten().sort()"

      }
    }
  }
}'
Run Code Online (Sandbox Code Playgroud)

调用将返回:

{
  "took": 50,
  "timed_out": false,
  "_shards": {
    "total": 6,
    "successful": 6,
    "failed": 0
  },
  "hits": {
    "total": 2,
    "max_score": 0,
    "hits": []
  },
  "aggregations": {
    "fooreduced": {
      "value": [
        1,
        2,
        3,
        4,
        5,
        6
      ]
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

可能有一个解决方案 withoun .flatten(),但我不太喜欢 groovy(还)来找到这样的解决方案。而且我不能说这种聚合的性能有多好,你必须自己测试。