Link Search Menu Expand Document Documentation Menu

词项聚合

terms 聚合为字段的每个唯一词项动态创建一个桶。

以下示例使用 terms 聚合来查找 Web 日志数据中每个响应码的文档数量

GET opensearch_dashboards_sample_data_logs/_search
{
  "size": 0,
  "aggs": {
    "response_codes": {
      "terms": {
        "field": "response.keyword",
        "size": 10
      }
    }
  }
}

示例响应

...
"aggregations" : {
  "response_codes" : {
    "doc_count_error_upper_bound" : 0,
    "sum_other_doc_count" : 0,
    "buckets" : [
      {
        "key" : "200",
        "doc_count" : 12832
      },
      {
        "key" : "404",
        "doc_count" : 801
      },
      {
        "key" : "503",
        "doc_count" : 441
      }
    ]
  }
 }
}

这些值以键 key 返回。doc_count 指定每个桶中的文档数量。默认情况下,桶按 doc-count 的降序排序。

可以使用 terms 通过按升序计数 ("order": {"count": "asc"}) 对返回的值进行排序来搜索不常见的值。但是,我们强烈不建议这样做,因为当涉及多个分片时,这可能导致不准确的结果。一个全局不常见的词项可能不会在每个单独的分片上显示为不常见,或者可能完全不存在于某些分片返回的最不频繁的结果中。相反,在一个分片上不常见的词项可能在另一个分片上很常见。在这两种情况下,稀有词项都可能在分片级别聚合期间被遗漏,导致整体结果不正确。因此,我们建议使用专门设计用于更准确处理这些情况的 rare_terms 聚合,而不是 terms 聚合。

大小和分片大小参数

terms 聚合返回的桶数量由 size 参数控制,该参数默认为 10。

此外,负责聚合的协调节点将提示每个分片提供其最独特的词项。每个分片返回的桶数量由 shard_size 参数控制。此参数与 size 参数不同,它的存在是为了提高桶文档计数的准确性。

例如,想象一个场景,其中 sizeshard_size 参数的值都为 3。terms 聚合提示每个分片提供其最独特的三项。协调节点聚合结果以计算最终结果。如果分片包含不在前三名中的对象,则它不会显示在响应中。但是,增加此请求的 shard_size 值将允许每个分片返回更多独特的词项,从而增加协调节点收到所有相关结果的可能性。

默认情况下,shard_size 参数设置为 size * 1.5 + 10

当使用并发段搜索时,shard_size 参数也应用于每个段切片。

shard_size 参数用于平衡 terms 聚合的性能和文档计数准确性。较高的 shard_size 值将确保更高的文档计数准确性,但会导致更高的内存和计算使用量。较低的 shard_size 值将具有更好的性能,但会导致较低的文档计数准确性。

文档计数误差

响应还包括两个键,名为 doc_count_error_upper_boundsum_other_doc_count

terms 聚合返回最独特的词项。因此,如果数据包含许多独特的词项,则其中一些可能不会出现在结果中。sum_other_doc_count 字段表示从响应中排除的文档总数。在这种情况下,该数字为 0,因为所有唯一值都出现在响应中。

doc_count_error_upper_bound 字段表示从最终结果中排除的唯一值的最大可能计数。使用此字段来估计计数的误差范围。

doc_count_error_upper_bound 值和准确性概念仅适用于使用默认排序顺序(按文档计数降序)的聚合。这是因为当您按文档计数降序排序时,任何未返回的词项都保证包含的文档数量等于或少于已返回的词项。基于此,您可以计算 doc_count_error_upper_bound

如果 show_term_doc_count_error 参数设置为 true,则 terms 聚合除了显示总体值外,还会显示为每个唯一桶计算的 doc_count_error_upper_bound

min_doc_countshard_min_doc_count 参数

您可以使用 min_doc_count 参数来过滤掉结果少于 min_doc_count 的任何唯一词项。min_doc_count 阈值仅在合并从所有分片检索到的结果后应用。每个分片都不知道给定词项的全局文档计数。如果全局频繁的前 shard_size 词项与分片本地的最频繁词项之间存在显著差异,则在使用 min_doc_count 参数时可能会收到意外结果。

另外,shard_min_doc_count 参数用于过滤掉分片返回给协调器且结果少于 shard_min_doc_count 的唯一词项。

当使用并发段搜索时,shard_min_doc_count 参数不应用于每个段切片。有关更多信息,请参阅相关的 GitHub 问题

收集模式

有两种可用的收集模式:depth_firstbreadth_firstdepth_first 收集模式以深度优先方式扩展聚合树的所有分支,并且仅在扩展完成后执行修剪。

然而,当使用嵌套的 terms 聚合时,返回桶数量的基数会乘以每个嵌套级别字段的基数,这使得在嵌套聚合时很容易看到桶数量的组合式爆炸。

您可以使用 breadth_first 收集模式来解决这个问题。在这种情况下,修剪将应用于聚合树的第一级,然后才扩展到下一级,这可能大大减少计算的桶数量。

此外,执行 breadth_first 收集会产生内存开销,这与匹配文档的数量呈线性关系。这是因为 breadth_first 收集通过缓存和重放父级别修剪过的桶集来工作。

考虑预聚合数据

虽然 doc_count 字段表示桶中聚合的单个文档数量,但 doc_count 本身无法正确递增存储预聚合数据的文档。为了考虑预聚合数据并准确计算桶中的文档数量,您可以使用 _doc_count 字段在单个汇总字段中添加文档数量。当文档包含 _doc_count 字段时,所有桶聚合都会识别其值并累积增加桶的 doc_count。使用 _doc_count 字段时请牢记以下注意事项:

  • 该字段不支持嵌套数组;只能使用正整数。
  • 如果文档不包含 _doc_count 字段,聚合将使用该文档将计数增加 1。

依赖准确文档计数的 OpenSearch 功能说明了使用 _doc_count 字段的重要性。要了解如何使用此字段支持其他搜索工具,请参阅索引汇总,这是一个用于索引管理 (IM) 插件的 OpenSearch 功能,它将预聚合数据存储在汇总索引中。

请求示例

PUT /my_index/_doc/1
{
  "response_code": 404,
  "date":"2022-08-05",
  "_doc_count": 20
}

PUT /my_index/_doc/2
{
  "response_code": 404,
  "date":"2022-08-06",
  "_doc_count": 10
}

PUT /my_index/_doc/3
{
  "response_code": 200,
  "date":"2022-08-06",
  "_doc_count": 300
}

GET /my_index/_search
{
  "size": 0,
  "aggs": {
    "response_codes": {
      "terms": {
        "field" : "response_code"
      }
    }
  }
}

示例响应

{
  "took" : 20,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 3,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
    "response_codes" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [
        {
          "key" : 200,
          "doc_count" : 300
        },
        {
          "key" : 404,
          "doc_count" : 30
        }
      ]
    }
  }
}
剩余 350 字符

有问题?

想贡献吗?