13

我正在使用 Elasticsearch 2.3,并且正在尝试使用管道聚合执行两步计算。我只对管道聚合的最终结果感兴趣,但 Elasticsearch 会返回所有存储桶信息。

由于我有大量的桶(数千万或数亿),这是令人望而却步的。不幸的是,我找不到方法告诉 Es 不要返回所有这些信息。

这是一个玩具示例。我有test-index一个文档类型的索引objobj有两个字段,key并且values.

curl -XPOST 'http://10.10.0.7:9200/test-index/obj' -d '{
  "value": 100,
  "key": "foo"
}'

curl -XPOST 'http://10.10.0.7:9200/test-index/obj' -d '{
  "value": 20,
  "key": "foo"
}'

curl -XPOST 'http://10.10.0.7:9200/test-index/obj' -d '{
  "value": 50,
  "key": "bar"
}'

curl -XPOST 'http://10.10.0.7:9200/test-index/obj' -d '{
  "value": 60,
  "key": "bar"
}'

curl -XPOST 'http://10.10.0.7:9200/test-index/obj' -d '{
  "value": 70,
  "key": "bar"
}'

我想获得具有相同skey的最小值的平均值(在所有 svalue上)。最小值的平均值。objkey

Elasticsearch 允许我这样做:

curl -XPOST 'http://10.10.0.7:9200/test-index/obj/_search' -d '{
  "size": 0,
  "query": {
    "match_all": {}
  },
  "aggregations": {
    "key_aggregates": {
      "terms": {
        "field": "key",
        "size": 0
      },
      "aggs": {
        "min_value": {
          "min": {
            "field": "value"
          }
        }
      }
    },
    "avg_min_value": {
      "avg_bucket": {
        "buckets_path": "key_aggregates>min_value"
      }
    }
  }
}'

但是这个查询返回每个桶的最小值,虽然我不需要它:

{
  "took": 21,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 4,
    "max_score": 0,
    "hits": [

    ]
  },
  "aggregations": {
    "key_aggregates": {
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": [
        {
          "key": "bar",
          "doc_count": 2,
          "min_value": {
            "value": 50
          }
        },
        {
          "key": "foo",
          "doc_count": 2,
          "min_value": {
            "value": 20
          }
        }
      ]
    },
    "avg_min_value": {
      "value": 35
    }
  }
}

有没有办法摆脱里面的所有信息"buckets": [...]?我只对avg_min_value.

在这个玩具示例中这似乎不是问题,但是当不同keys 的数量不大(数千万或数亿)时,查询响应大得令人望而却步,我想对其进行修剪。

有没有办法用 Elasticsearch 做到这一点?还是我对数据的建模错误?

注意:预先聚合每个键的数据是不可接受的,因为match_all我的查询部分可能会被复杂和未知的过滤器替换。

NB2:size在我的聚合中更改为非负数terms是不可接受的,因为它会改变结果。

4

1 回答 1

19

我遇到了同样的问题,经过大量研究后,我找到了解决方案,并认为我会在这里分享。

您可以使用响应过滤功能来过滤您想要接收的部分答案。

filter_path=aggregations.avg_min_value您应该能够通过将查询参数添加到搜索 URL来实现您想要的。在示例情况下,它应该类似于以下内容:

curl -XPOST 'http://10.10.0.7:9200/test-index/obj/_search?filter_path=aggregations.avg_min_value' -d '{
  "size": 0,
  "query": {
    "match_all": {}
  },
  "aggregations": {
    "key_aggregates": {
      "terms": {
        "field": "key",
        "size": 0
      },
      "aggs": {
        "min_value": {
          "min": {
            "field": "value"
          }
        }
      }
    },
    "avg_min_value": {
      "avg_bucket": {
        "buckets_path": "key_aggregates>min_value"
      }
    }
  }
}'

PS:如果您找到其他解决方案,您介意在这里分享吗?谢谢!

于 2016-12-18T03:55:25.580 回答