聚合

edit

聚合将您的数据总结为指标、统计数据或其他分析。 聚合帮助您回答以下问题:

  • 我的网站的平均加载时间是多少?
  • 根据交易量,谁是我最有价值的客户?
  • 在我的网络中,什么会被认为是一个大文件?
  • 每个产品类别中有多少种产品?

Elasticsearch 将聚合组织为三个类别:

  • Metric 聚合,用于计算字段值的指标,如总和或平均值。
  • Bucket 聚合,根据字段值、范围或其他标准将文档分组到桶(也称为bin)中。
  • Pipeline 聚合,从其他聚合而不是文档或字段中获取输入。

运行聚合

edit

您可以通过指定搜索搜索 APIaggs参数,在搜索过程中运行聚合。以下搜索在my-field上运行一个词条聚合

GET /my-index-000001/_search
{
  "aggs": {
    "my-agg-name": {
      "terms": {
        "field": "my-field"
      }
    }
  }
}

聚合结果在响应的 aggregations 对象中:

{
  "took": 78,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 5,
      "relation": "eq"
    },
    "max_score": 1.0,
    "hits": [...]
  },
  "aggregations": {
    "my-agg-name": {                           
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": []
    }
  }
}

关于 my-agg-name 聚合的结果。

更改聚合的范围

edit

使用 query 参数来限制聚合运行的文档:

GET /my-index-000001/_search
{
  "query": {
    "range": {
      "@timestamp": {
        "gte": "now-1d/d",
        "lt": "now/d"
      }
    }
  },
  "aggs": {
    "my-agg-name": {
      "terms": {
        "field": "my-field"
      }
    }
  }
}

仅返回聚合结果

edit

默认情况下,包含聚合的搜索会返回搜索命中结果和聚合结果。要仅返回聚合结果,请将size设置为0

GET /my-index-000001/_search
{
  "size": 0,
  "aggs": {
    "my-agg-name": {
      "terms": {
        "field": "my-field"
      }
    }
  }
}

运行多个聚合

edit

您可以在同一请求中指定多个聚合:

GET /my-index-000001/_search
{
  "aggs": {
    "my-first-agg-name": {
      "terms": {
        "field": "my-field"
      }
    },
    "my-second-agg-name": {
      "avg": {
        "field": "my-other-field"
      }
    }
  }
}

运行子聚合

edit

桶聚合支持桶或指标子聚合。例如,一个带有平均值子聚合的术语聚合会为每个文档桶计算一个平均值。嵌套子聚合的层级或深度没有限制。

GET /my-index-000001/_search
{
  "aggs": {
    "my-agg-name": {
      "terms": {
        "field": "my-field"
      },
      "aggs": {
        "my-sub-agg-name": {
          "avg": {
            "field": "my-other-field"
          }
        }
      }
    }
  }
}

响应将子聚合结果嵌套在其父聚合下:

{
  ...
  "aggregations": {
    "my-agg-name": {                           
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": [
        {
          "key": "foo",
          "doc_count": 5,
          "my-sub-agg-name": {                 
            "value": 75.0
          }
        }
      ]
    }
  }
}

父聚合的结果,my-agg-name

关于 my-agg-name 的子聚合 my-sub-agg-name 的结果。

添加自定义元数据

edit

使用 meta 对象将自定义元数据与聚合关联起来:

GET /my-index-000001/_search
{
  "aggs": {
    "my-agg-name": {
      "terms": {
        "field": "my-field"
      },
      "meta": {
        "my-metadata-field": "foo"
      }
    }
  }
}

响应返回了 meta 对象:

{
  ...
  "aggregations": {
    "my-agg-name": {
      "meta": {
        "my-metadata-field": "foo"
      },
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": []
    }
  }
}

返回聚合类型

edit

默认情况下,聚合结果包括聚合的名称但不包括其类型。 要返回聚合类型,请使用 typed_keys 查询参数。

GET /my-index-000001/_search?typed_keys
{
  "aggs": {
    "my-agg-name": {
      "histogram": {
        "field": "my-field",
        "interval": 1000
      }
    }
  }
}

响应将聚合类型作为前缀返回给聚合的名称。

一些聚合返回的聚合类型与请求中的类型不同。例如,terms、 significant terms、 和 percentiles 聚合根据聚合字段的数据类型返回不同的聚合类型。

{
  ...
  "aggregations": {
    "histogram#my-agg-name": {                 
      "buckets": []
    }
  }
}

聚合类型,histogram,后面跟着一个#分隔符和聚合的名称,my-agg-name

在聚合中使用脚本

edit

当一个字段不完全匹配您所需的聚合时,您应该在运行时字段上进行聚合:

GET /my-index-000001/_search?size=0
{
  "runtime_mappings": {
    "message.length": {
      "type": "long",
      "script": "emit(doc['message.keyword'].value.length())"
    }
  },
  "aggs": {
    "message_length": {
      "histogram": {
        "interval": 10,
        "field": "message.length"
      }
    }
  }
}

脚本动态计算字段值,这会给聚合增加一些开销。除了计算所花费的时间外,一些聚合如termsfilters无法在使用运行时字段时使用它们的一些优化。总的来说,使用运行时字段的性能成本因聚合而异。

聚合缓存

edit

为了更快地响应,Elasticsearch 将频繁运行的聚合结果缓存在 分片请求缓存中。要获取缓存的结果,请为每次搜索使用相同的 preference 字符串。如果你不需要搜索命中结果, size 设置为 0 以避免填充缓存。

Elasticsearch 将具有相同偏好字符串的搜索路由到相同的分片。如果分片的数据在搜索之间没有变化,分片将返回缓存的聚合结果。

long 值的限制

edit

在运行聚合时,Elasticsearch 使用 double 值来保存和表示数值数据。因此,对大于 253long 数字进行聚合时,结果是近似的。