【问题标题】:elasticsearch group every X values弹性搜索组每 X 个值
【发布时间】:2016-02-26 01:10:01
【问题描述】:

使用 elasticsearch,我查询特定字段。那么有没有办法聚合每个 X 值?

例如,假设我为字段“myField”查询 10 个文档,返回 10 个值,

1、4、2、4、5、3、3、2、1、4。

有没有一种方法可以聚合使得每 2 个值被平均,产生

2.5, 3, 4, 2.5, 2.5 ?

【问题讨论】:

  • 这是一个有趣的要求...这些值的平均顺序是否重要?您可以按不同的顺序获取它们,这会改变每个平均值。我不确定有没有办法做到这一点,但你有理由不在应用程序端这样做吗?
  • 是的,我会事先订购这些值。我可以在应用程序端做,是的,但是出于可扩展性的目的,我想知道它是否可以通过 elasticsearch 来完成。我最终可能要汇总数百万个文档。
  • 我认为您可以使用脚本化的指标聚合来设置它,但这将是一个彻底的黑客攻击。不确定可重复性。
  • 使用弹性搜索或应用程序端的“脚本化指标聚合”? IE。这个聚合会在什么时候出现,它会是什么样子,@SloanAhrens?
  • 让我看看能不能举个例子。

标签: elasticsearch aggregate aggregation sequential


【解决方案1】:

您可以使用scripted metric aggregations 做一些有趣的——也许是不可取的——事情。它们允许您定义针对您的文档运行的 map-reduce 脚本。当然,你可能会因此惹上麻烦。

但为了看看我能不能做到,我用您提供的数据建立了一个简单的单分片索引:

PUT /test_index
{"settings": {"number_of_shards": 1}}

POST /test_index/doc/_bulk
{"index":{"_id":1}}
{"num":1}
{"index":{"_id":2}}
{"num":4}
{"index":{"_id":3}}
{"num":2}
{"index":{"_id":4}}
{"num":4}
{"index":{"_id":5}}
{"num":5}
{"index":{"_id":6}}
{"num":3}
{"index":{"_id":7}}
{"num":3}
{"index":{"_id":8}}
{"num":2}
{"index":{"_id":9}}
{"num":1}
{"index":{"_id":10}}
{"num":4}

然后我可以像这样平均每两个文档:

POST /test_index/_search
{
    "size": 0,
    "aggs": {
        "profit": {
            "scripted_metric": {
                "init_script" : "_agg['nums'] = []; _agg['avgs'] = [];",
                "map_script" : "_agg.nums.add(doc['num'].value); if(_agg.nums.size() == 2){ _agg.avgs.add((_agg.nums[0] + _agg.nums[1])/2.0); _agg['nums'] = [];}", 
                "combine_script" : "return _agg.avgs",
                "reduce_script" : "return _aggs"
            }
        }
    }
}
...
{
   "took": 2,
   "timed_out": false,
   "_shards": {
      "total": 1,
      "successful": 1,
      "failed": 0
   },
   "hits": {
      "total": 10,
      "max_score": 0,
      "hits": []
   },
   "aggregations": {
      "profit": {
         "value": [
            [
               2.5,
               3,
               4,
               2.5,
               2.5
            ]
         ]
      }
   }
}

它似乎不尊重查询中的排序顺序,尽管据我所知结果是确定性的。

我在这里所做的仅适用于单个分片;如果你想修改它足够长的时间,你可能会以某种方式概括它。

另外,大胖免责声明:在生产中这样做可能不是一个好主意。在您可能因内存不足错误导致集群崩溃之前,您需要先在小型数据集上测试此类事情。此外,仅当您的集群未对严重的 Internet 开放时才使用脚本。

这是我用来玩它的一些代码:

http://sense.qbox.io/gist/c31f089e63200127fd9ca09992004db8bb11b890

【讨论】:

  • 哇,感谢您花时间研究这个!不幸的是,我认为由于您提到的问题(仅使用单个分片,并且不尊重排序顺序),我将不得不在应用程序端进行此操作。希望这个解决方案能在未来对我或其他人有所帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-09-11
  • 2021-11-23
  • 2023-04-06
  • 2018-10-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多