稀有词项聚合
rare_terms
聚合是一种桶聚合,用于识别数据集中不常见的词项。与查找最常见词项的 terms
聚合相反,rare_terms
聚合查找出现频率最低的词项。rare_terms
聚合适用于异常检测、长尾分析和异常报告等应用。
可以通过按升序计数 ("order": {"count": "asc"}
) 对返回的值进行排序来使用 terms
搜索不常见的值。然而,我们强烈不建议这样做,因为它在涉及多个分片时可能导致结果不准确。全局不常见的词项可能不会在每个单独的分片上都显得不常见,或者可能完全不存在于某些分片返回的最低频率结果中。相反,在一个分片上不常见的词项可能在另一个分片上很常见。在这两种情况下,稀有词项都可能在分片级别聚合期间被遗漏,导致整体结果不正确。我们建议使用 rare_terms
聚合而不是 terms
聚合,因为它专门设计用于更准确地处理这些情况。
近似结果
计算 rare_terms
聚合的精确结果需要编译所有分片上值的完整映射,这会消耗过多的运行时内存。因此,rare_terms
聚合结果是近似的。
rare_terms
计算中的大多数错误都是**假阴性**或“遗漏”值,这定义了聚合检测测试的**灵敏度**。rare_terms
聚合使用 CuckooFilter 算法来平衡适当的灵敏度和可接受的内存使用。有关 CuckooFilter 算法的描述,请参阅这篇论文。
控制灵敏度
rare_terms
聚合算法中的灵敏度误差被测量为被遗漏的稀有值的比例,即 假阴性/目标值
。例如,如果聚合在一个包含 5,000 个稀有值的数据集中遗漏了 100 个稀有值,则灵敏度误差为 100/5000 = 0.02
,即 2%。
您可以调整 rare_terms
聚合中的 precision
参数来控制灵敏度和内存使用之间的权衡。
这些因素也会影响灵敏度-内存权衡
- 唯一值的总数
- 数据集中稀有项的比例
以下指南可以帮助您决定使用哪个 precision
值。
计算内存使用
运行时内存使用以绝对术语描述,通常以 RAM 的 MB 为单位。
内存使用随唯一项的数量线性增加。线性缩放因子在每 1 百万个唯一值 1.0 到 2.5 MB 之间变化,具体取决于 precision
参数。对于默认精度 0.001
,每 1 百万个唯一值的内存成本约为 1.75 MB。
管理灵敏度误差
灵敏度误差随唯一值的总数线性增加。有关估计唯一值数量的信息,请参阅Cardinality aggregation。
即使对于包含 10-20 百万唯一值的数据集,在默认 precision
下,灵敏度误差也很少超过 2.5%。对于 0.00001
的 precision
,灵敏度误差很少高于 0.6%。然而,稀有值绝对数量非常低可能会导致错误率的巨大差异(如果只有两个稀有值,遗漏其中一个会导致 50% 的错误率)。
与其他聚合的兼容性
rare_terms
聚合使用广度优先收集模式,并且与某些子聚合和嵌套配置中需要深度优先收集模式的聚合不兼容。
有关 OpenSearch 中广度优先搜索的更多信息,请参阅收集模式。
参数
rare_terms
聚合接受以下参数。
参数 | 必需/可选 | 数据类型 | 描述 |
---|---|---|---|
field | 必需 | 字符串 | 用于分析稀有词项的字段。必须是数值类型或带有 keyword 映射的文本类型。 |
max_doc_count | 可选 | 整数 | 词项被认为是稀有的所需的最大文档计数。默认值为 1 。最大值为 100 。 |
precision(精度) | 可选 | 整数 | 控制用于识别稀有词项的算法的精度。值越高,结果越精确,但消耗的内存越多。默认值为 0.001 。最小(允许的最精确)值为 0.00001 。 |
include | 可选 | 数组/正则表达式 | 要包含在结果中的词项。可以是正则表达式或值数组。 |
exclude | 可选 | 数组/正则表达式 | 要从结果中排除的词项。可以是正则表达式或值数组。 |
missing | 可选 | 字符串 | 用于聚合字段中没有值的文档的值。 |
示例
以下请求返回 OpenSearch Dashboards 示例航班数据中仅出现一次的所有目的地机场代码
GET /opensearch_dashboards_sample_data_flights/_search
{
"size": 0,
"aggs": {
"rare_destination": {
"rare_terms": {
"field": "DestAirportID",
"max_doc_count": 1
}
}
}
}
示例响应
响应显示有两个机场符合数据中仅出现一次的条件
{
"took": 12,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 10000,
"relation": "gte"
},
"max_score": null,
"hits": []
},
"aggregations": {
"rare_destination": {
"buckets": [
{
"key": "ADL",
"doc_count": 1
},
{
"key": "BUF",
"doc_count": 1
}
]
}
}
}
文档计数限制
使用 max_doc_count
参数指定 rare_terms
聚合可以返回的最大文档计数。rare_terms
返回的词项数量没有限制,因此大的 max_doc_count
值可能会返回非常大的结果集。因此,100
是允许的最大 max_doc_count
。
以下请求返回 OpenSearch Dashboards 示例航班数据中最多出现两次的所有目的地机场代码
GET /opensearch_dashboards_sample_data_flights/_search
{
"size": 0,
"aggs": {
"rare_destination": {
"rare_terms": {
"field": "DestAirportID",
"max_doc_count": 2
}
}
}
}
响应显示有七个目的地机场代码符合出现在两个或更少文档中的条件,其中包括前一个示例中的两个
{
"took": 6,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 10000,
"relation": "gte"
},
"max_score": null,
"hits": []
},
"aggregations": {
"rare_destination": {
"buckets": [
{
"key": "ADL",
"doc_count": 1
},
{
"key": "BUF",
"doc_count": 1
},
{
"key": "ABQ",
"doc_count": 2
},
{
"key": "AUH",
"doc_count": 2
},
{
"key": "BIL",
"doc_count": 2
},
{
"key": "BWI",
"doc_count": 2
},
{
"key": "MAD",
"doc_count": 2
}
]
}
}
}
过滤(包含和排除)
使用 include
和 exclude
参数过滤 rare_terms
聚合返回的值。这两个参数可以包含在同一个聚合中。exclude
过滤器优先;任何被排除的值都会从结果中移除,无论它们是否被明确包含。
include
和 exclude
的参数可以是正则表达式 (regex),包括字符串字面量,或数组。混合正则表达式和数组参数会导致错误。例如,以下组合是不允许的
"rare_terms": {
"field": "DestAirportID",
"max_doc_count": 2,
"exclude": ["ABQ", "AUH"],
"include": "A.*"
}
示例:过滤
以下示例修改了之前的示例,以包含所有以“A”开头的机场代码,但排除“ABQ”机场代码
GET /opensearch_dashboards_sample_data_flights/_search
{
"size": 0,
"aggs": {
"rare_destination": {
"rare_terms": {
"field": "DestAirportID",
"max_doc_count": 2,
"include": "A.*",
"exclude": "ABQ"
}
}
}
}
响应显示了符合过滤要求的两个机场代码
{
"took": 4,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 10000,
"relation": "gte"
},
"max_score": null,
"hits": []
},
"aggregations": {
"rare_destination": {
"buckets": [
{
"key": "ADL",
"doc_count": 1
},
{
"key": "AUH",
"doc_count": 2
}
]
}
}
}
示例:使用数组输入进行过滤
以下示例返回 OpenSearch Dashboards 示例航班数据中最多出现两次的所有目的地机场代码,但指定了一个要排除的机场代码数组
GET /opensearch_dashboards_sample_data_flights/_search
{
"size": 0,
"aggs": {
"rare_destination": {
"rare_terms": {
"field": "DestAirportID",
"max_doc_count": 2,
"exclude": ["ABQ", "BIL", "MAD"]
}
}
}
}
响应省略了被排除的机场代码
{
"took": 6,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 10000,
"relation": "gte"
},
"max_score": null,
"hits": []
},
"aggregations": {
"rare_destination": {
"buckets": [
{
"key": "ADL",
"doc_count": 1
},
{
"key": "BUF",
"doc_count": 1
},
{
"key": "AUH",
"doc_count": 2
},
{
"key": "BWI",
"doc_count": 2
}
]
}
}
}