Bootstrap

【Elasticsearch】significant_terms聚合

 `significant_terms` 聚合是 Elasticsearch 中一种用于发现文档中显著(或异常)词汇的聚合方法。它主要用于分析一个给定的数据集与另一个参考数据集之间的词汇分布差异。这个聚合可以用来识别那些在特定文档集合中出现频率异常高或低的词汇,从而帮助用户理解这些文档的独特性。

### 工作原理

`significant_terms` 聚合通过计算每个术语的统计显著性来工作。它基于这样一个假设:如果某个术语在目标数据集中比在背景数据集中更频繁地出现,那么这个术语对于目标数据集来说可能是重要的或者是有特殊意义的。聚合会计算每个术语的得分,该得分反映了该术语在目标数据集中的重要性。

### 统计方法

`significant_terms` 聚合使用了多种统计测试来确定术语的重要性,包括但不限于:

- **G值** (G-value):这是一种基于似然比检验的方法,用于比较两个比例之间的差异。

- **卡方检验** (Chi-squared test):用于检测两个变量之间是否存在关联。

- **JLH得分** (JLH score):这是一个简单的得分函数,考虑了术语的频率和文档频率。

### 使用场景

- **异常检测**:识别文档中异常的或者不寻常的术语。

- **关键词提取**:从大量的文本数据中自动提取关键词。

- **内容分析**:帮助理解特定文档集合的内容特征,比如分析新闻文章、社交媒体帖子等。

### 配置参数

使用 `significant_terms` 聚合时,可以通过以下参数进行配置:

- `field`:指定要聚合的字段。

- `size`:限制返回的显著术语的数量。

- `include` 和 `exclude`:用于包含或排除特定的术语模式。

- `min_doc_count`:设置术语至少需要出现在多少个文档中才能被考虑。

- `shard_size`:控制每个分片返回的术语数量,以影响聚合的准确性和性能。

### 示例

假设我们有一个索引,其中包含了多个博客文章,我们想要找出某个特定标签下的文章中哪些词汇是特别显著的。我们可以使用如下查询:

```json

GET /blogs/_search

{

  "size": 0,

  "query": {

    "term": {

      "tags": "technology"

    }

  },

  "aggs": {

    "significant_words": {

      "significant_terms": {

        "field": "content.keyword",

        "size": 10

      }

    }

  }

}

```

在这个例子中,我们首先通过 `term` 查询选择了带有 "technology" 标签的文章,然后应用了 `significant_terms` 聚合来找出这些文章中最重要的10个词汇。

### 注意事项

- `significant_terms` 聚合可能会消耗较多资源,尤其是在处理大量数据时。因此,在设计查询时应注意性能优化。

- 选择合适的统计方法和参数对于获得有意义的结果至关重要。

- 在某些情况下,可能需要对数据进行预处理,例如去除停用词,以提高聚合结果的质量。

在 `significant_terms` 聚合中,给定的数据集和参考数据集的概念是相对的,通常取决于你的查询条件和聚合的上下文。在你提供的示例中:

```json
GET /blogs/_search
{
  "size": 0,
  "query": {
    "term": {
      "tags": "technology"
    }
  },
  "aggs": {
    "significant_words": {
      "significant_terms": {
        "field": "content.keyword",
        "size": 10
      }
    }
  }
}
```

### 解释

- **给定的数据集**:这是你通过查询条件过滤出的文档集合。在这个例子中,给定的数据集是所有带有 "technology" 标签的博客文章。这些文章是你关注的重点,你希望在这部分文档中找到显著的词汇。

- **参考数据集**:这是整个索引中的所有文档,即没有经过任何过滤的文档集合。在 `significant_terms` 聚合中,默认情况下,参考数据集是整个索引中的所有文档。Elasticsearch 会将给定的数据集中的术语频率与参考数据集中的术语频率进行比较,以确定哪些术语在给定的数据集中是显著的。

### 具体过程

1. **查询条件**:`"term": { "tags": "technology" }` 这个查询条件将筛选出所有带有 "technology" 标签的博客文章。这些文章构成了给定的数据集。
2. **聚合**:`"significant_terms": { "field": "content.keyword", "size": 10 }` 这个聚合将在这部分文章中找出最显著的10个词汇。
3. **比较**:Elasticsearch 会将这些文章中的术语频率与整个索引中的术语频率进行比较,以确定哪些术语在带有 "technology" 标签的文章中出现得更频繁,从而认为这些术语是显著的。

### 总结

- **给定的数据集**:所有带有 "technology" 标签的博客文章。
- **参考数据集**:整个 `blogs` 索引中的所有博客文章。

通过这种方式,`significant_terms` 聚合可以帮助你识别出在特定标签下的文章中哪些词汇是特别重要或显著的。

`execution_hint` 是 `significant_terms` 聚合中的一个可选参数,用于指导 Elasticsearch 如何执行聚合计算。这个参数可以帮助优化性能,特别是在处理大量数据时。`execution_hint` 提供了几种不同的策略,每种策略都有其特定的适用场景和优缺点。

### 可用的 `execution_hint` 值

1. **`map`**:
   - **描述**:这是默认的执行策略。Elasticsearch 会在每个分片上独立地计算显著术语,然后将结果合并到最终的聚合结果中。
   - **优点**:适用于大多数情况,性能较好。
   - **缺点**:在某些情况下,可能会导致内存使用较高,特别是在术语数量非常大的情况下。

2. **`global_ordinals`**:
   - **描述**:使用全局序数(global ordinals)来加速术语的查找和计数。全局序数是一种将字符串映射到整数的技术,可以减少内存使用并加快计算速度。
   - **优点**:在术语数量较少且预先构建了全局序数的情况下,性能非常好。
   - **缺点**:需要额外的内存来存储全局序数,且在术语数量非常大时可能不如 `map` 策略高效。

3. **`fielddata`**:
   - **描述**:使用字段数据(fielddata)来执行聚合。字段数据是将字符串值加载到内存中的技术,可以提供快速的访问速度。
   - **优点**:适用于需要频繁访问字段值的情况,可以提供较快的性能。
   - **缺点**:需要较多的内存来存储字段数据,可能导致内存使用增加。

### 使用场景

- **`map`**:适用于大多数情况,特别是当术语数量适中且不需要特别优化性能时。
- **`global_ordinals`**:适用于术语数量较少且预先构建了全局序数的情况,可以显著提升性能。
- **`fielddata`**:适用于需要频繁访问字段值的情况,特别是当字段数据已经加载到内存中时。

### 示例

假设我们有一个索引,其中包含了多个博客文章,我们想要找出某个特定标签下的文章中哪些词汇是特别显著的,并且我们希望使用 `global_ordinals` 策略来优化性能。我们可以使用如下查询:

```json
GET /blogs/_search
{
  "size": 0,
  "query": {
    "term": {
      "tags": "technology"
    }
  },
  "aggs": {
    "significant_words": {
      "significant_terms": {
        "field": "content.keyword",
        "size": 10,
        "execution_hint": "global_ordinals"
      }
    }
  }
}
```

### 注意事项

- **内存使用**:不同的 `execution_hint` 策略对内存的影响不同。在选择策略时,需要权衡性能和内存使用。
- **预构建全局序数**:使用 `global_ordinals` 策略时,确保全局序数已经预先构建。这可以通过定期刷新索引来实现。
- **字段数据**:使用 `fielddata` 策略时,确保字段数据已经加载到内存中。这可以通过显式地请求字段数据或使用动态字段数据加载来实现。

通过合理选择 `execution_hint`,可以显著提升 `significant_terms` 聚合的性能,特别是在处理大规模数据集时。

;