【问题标题】:How to combine multiple aggs in Elasticsearch?如何在 Elasticsearch 中组合多个 aggs?
【发布时间】:2018-12-17 18:19:48
【问题描述】:

我想计算一天内每个产品的每个 IP 访问次数。

一个索引(nginx-access-log)中有三个参数:

  • 时间戳
  • clientip
  • product_id

我知道date_histogram可以参考https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-datehistogram-aggregation.html

而count可以参考https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-cardinality-aggregation.html#_precision_control

但我不知道如何组合 aggs 来构建脚本。


更新:

我使用下面的脚本来搜索

GET log-nginx_access*/_search 
{
  "aggs": {
    "by_day": {
      "date_histogram": {
        "field": "timestamp",
        "interval": "1d",
        "time_zone": "Asia/Shanghai",
        "min_doc_count": 1
      },
      "aggs": {
        "by_product": {
          "terms": {
            "field": "uri_args.product_id",
            "size": 100
          }
        },
        "aggs": {
          "by_ip": {
            "terms": {
              "field": "clientip"
            }
          }
        }
      }
    }
  }
}

出现错误:

{
  "error": {
    "root_cause": [
      {
        "type": "unknown_named_object_exception",
        "reason": "Unknown BaseAggregationBuilder [by_ip]",
        "line": 18,
        "col": 20
      }
    ],
    "type": "unknown_named_object_exception",
    "reason": "Unknown BaseAggregationBuilder [by_ip]",
    "line": 18,
    "col": 20
  },
  "status": 400
}

【问题讨论】:

    标签: elasticsearch elasticsearch-aggregation


    【解决方案1】:

    也许我们可以使用termsdate_histogram 聚合

    参考:https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-terms-aggregation.html

    GET /{index_name}
    {  
      "aggs": {
        "by_day": {
          "date_histogram": {
            "field" : "timestamp",
            "interval" : "day"
          },
          "aggs": {
            "by_product": {
              "terms" : {
                "field" : "product",
                "size": 100 // 100 unique products will be aggregated
              },
              "aggs": {
                "by_ip": {
                  "terms" : {
                    "field" : "ip"
                  }
                }
              }
            }            
          }
        }
      }
    }
    

    terms 聚合的响应有 doc_count 字段,可以满足您的要求。我们必须考虑的一件事是size 参数来定义聚合的唯一性。

    【讨论】:

    • @Mithril 很有趣。你是在 Kibana 中执行它并得到那个错误吗?
    • 是的,我使用 Kibana - dev_tools 来测试脚本。
    • @Mithril 我错误地将by_ip aggs 放在了错误的位置。请使用更新的答案重试。
    • 谢谢!我首先了解 elasticsearch aggs timestamp,然后是每个间隔中的 aggs product - day,最后是每天每种产品的 aggs ip。这就是构造查询的方式。
    猜你喜欢
    • 2023-02-10
    • 2016-03-27
    • 1970-01-01
    • 2012-11-01
    • 2014-10-13
    • 2018-07-30
    • 2020-12-03
    • 1970-01-01
    相关资源
    最近更新 更多