# 基数聚合(Cardinality Aggregation)

single-value度量聚合就是计算单值的近似值。这些值可以从文本中获取或者使用脚本生成。

假设你正在建立书的索引，并且希望请求与作者唯一匹配：

```
{
    "aggs" : {
        "author_count" : {
            "cardinality" : {
                "field" : "author"
            }
        }
    }
}
```

## Precision Control

这个聚类操作支持precision\_threshold选项：

> 警告：precision\_threshold选项特定于当前内部实现的cardinality agg，它可能会在以后进行修改。

```
{
    "aggs" : {
        "author_count" : {
            "cardinality" : {
                "field" : "author_hash",
                "precision_threshold": 100
            }
        }
    }
}
```

precision\_threshold选项允许交易内存的准确性，并定义一个唯一的计数，低于该计数预计接近准确。 高于这个值，计数可能会变得更模糊。 支持的最大值为40000，超过此数字的阈值将具有与阈值40000相同的效果。默认值为3000。

## Counts are approximate

计算精确计数要求加载值到一个哈希集并返回它的大小，当工作在高基数时需要占用大量的内存空间，同时在节点间沟通每个分片集也会占用大量的集群资源，所以计算的效率是比较低的。

基数聚合基于[HyperLogLog++](http://static.googleusercontent.com/media/research.google.com/fr//pubs/archive/40671.pdf) 算法，这个算法基于散列值，它有以下这些有趣的性质：

* 可配置的精度，它决定为了准确性如何交换内存；
* 低基数集的优良精度；
* 固定内存使用：无论有几十或数十亿的唯一值，内存的使用仅取决于配置的精度。

对于c的精确阈值，我们的实现需要使用大约8字节。

下图显示了设置阈值前后误差如何变化：![](https://www.elastic.co/guide/en/elasticsearch/reference/current/images/cardinality_error.png)

对于所有3个阈值，计数已准确到配置阈值（虽然没有保证，这是可能的情况下）。请注意，即使有一个阈值低至100，错误仍然非常低，即使是数以百万计数据。

## Pre-computed hashes

在具有高基数的字符串字段中，在索引中存储字段值的哈希值可能更快，然后在该字段中运行基数聚合。可以在客户端计算出哈希值（再提供给es），也可以让elasticsearch使用[`mapper-murmur3`](https://www.elastic.co/guide/en/elasticsearch/plugins/5.3/mapper-murmur3.html)插件为你计算出哈希值。

> 预计算哈希值通常仅适用于非常大的和/或高基数字段，这样可以节省CPU和内存。然而，对于数字字段，计算哈希是非常快速的，存储原始的值需要的内存比存储计算出的哈希值可能更多也，可能更少（差不多，所以没必要使用预计算哈希值）。对于低基数字符串字段也是这样，特别是在那些优化确保每一段数据哈希值保持唯一值的情况下（也没必要使用预计算哈希值）。

## Script

基数聚合支持使用脚本，但是使用脚本会带来明显的性能损失：

```
{
    "aggs" : {
        "author_count" : {
            "cardinality" : {
                "script": {
                    "lang": "painless",
                    "inline": "doc['author.first_name'].value + ' ' + doc['author.last_name'].value"
                }
            }
        }
    }
}
```

上面的语句将会使用系统内置的脚本语言进行解释，而且是不带参数的。用一个文件脚本的完整语法如下：

```
{
    "aggs" : {
        "author_count" : {
            "cardinality" : {
                "script" : {
                    "file": "my_script",
                    "params": {
                        "first_name_field": "author.first_name",
                        "last_name_field": "author.last_name"
                    }
                }
            }
        }
    }
}
```

> 对于索引脚本只需要将file参数替换为id参数。

## Missing Value

Missing字段定义了文档缺失值的时候应该如何处理。默认情况下这些文档会被忽略，但是也可以认为它们有一个默认的值存在：

```
{
    "aggs" : {
        "tag_cardinality" : {
            "cardinality" : {
                "field" : "tag",
                "missing": "N/A"
            }
        }
    }
}
```

> 如果文档没有tag字段，则认为该文档的tag值为“N/A”。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://xiaoxiami.gitbook.io/elasticsearch/ji-chu/36aggregationsju-he-fen-679029/liang-du-ju-540828-metric-aggregations/ji-shu-ju-540828-cardinality-aggregation.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
