Elasticsearch -合并多个文档中的字段

axzmvihb  于 2023-06-05  发布在  ElasticSearch
关注(0)|答案(2)|浏览(463)

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

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

{
    "foo" : [3, 4, 5]
}

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

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

我已经研究了聚合API,但我不知道如何实现这一点,如果它在所有可能的。我当然可以用代码手动编译结果,但是我可以有成千上万的文档,以这种方式获得结果会更干净。

7ivaypg9

7ivaypg91#

您可以使用Scripted Metric Aggregation和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] }'

现在试试这个聚合:

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()"

      }
    }
  }
}'

调用将返回以下内容:

{
  "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
      ]
    }
  }
}

也许有一个解决方案没有oun .flatten(),但我还没有那么多到groovy(尚未)找到这样的解决方案。我不能说这个聚合的性能有多好,你必须自己测试它。

enxuqcxy

enxuqcxy2#

我用的方法

"scripted_metric": {
        "init_script": "state.userClients = []",
        "map_script": "for(d in doc['mycolumn'].value.splitOnToken(',')){state.userClients.add(d)}",
        "combine_script": "return state.userClients",
        "reduce_script": "def uniqueClients = new ArrayList(); for (state in states) { for(client in state){if(!uniqueClients.contains(client) && client != '' ) uniqueClients.add(client); }} return uniqueClients.length;"
      }

相关问题