问题域已经有了显示许多令牌的信息亭。令牌仅由一个发行者发行,并且可以存在于多个售货亭上。自助服务终端逻辑根据该自助服务终端上存在的令牌接受/拒绝用户。
我们的弹性映射是:
"mappings": {
"Kiosk": {
"dynamic": "strict",
"properties": {
"kioskId": {
"type": "keyword"
},
"token": {
"type": "nested",
"include_in_parent": true,
"properties": {
"tokenId": {
"type": "keyword"
},
"issuer": {
"type": "keyword"
}
}
}
}
}
}
以下是两个典型文件:
Kiosk1
"kioskId": "123",
"token": {
"tokenId": "fp1",
"issuer": "i1"
Kiosk2
"kioskId": "321",
"token": [
{
"tokenId": "fp1",
"issuer": "i1"
},
{
"tokenId": "fp2",
"issuer": "i2"
}
]
现在,问题是要找到发行人敲定的系统中所有唯一令牌的数量。找到它们没有运气。我们尝试了这个查询:
POST _search
{
"aggs": {
"state": {
"nested": {
"path": "token"
},
"aggs": {
"TOKENS_BY_ISSUER": {
"terms": {
"field": "token.issuer"
}
}
}
}
}
}
这显然给出了这个结果:
"aggregations": {
"state": {
"doc_count": 3,
"TOKENS_BY_ISSUER": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "i1",
"doc_count": 2
},
{
"key": "i2",
"doc_count": 1
}
]
}
}
}
有没有办法知道系统中只有两个令牌,每个令牌由i1和i2发出?像这样......
"buckets": [
{
"key": "i1",
"doc_count": 1
},
{
"key": "i2",
"doc_count": 1
}
]
如果没有,映射出错了哪里?我觉得这不是一个不寻常的映射。请注意,为了简洁起见,我已经截断了此处发布的映射,我们在令牌下进一步嵌套了级别。这些额外的嵌套级别带有特定于令牌及其父信息亭的字段。
答案 0 :(得分:0)
您可以更改查询以匹配此类
{
"query": {
"match_all": {}
},
"aggs":{
"state": {
"nested": {
"path": "token"
},
"aggs": {
"TOKENS_BY_ISSUER": {
"terms": {
"field": "token.issuer"
},
"aggs":{
"distinct_tokens":{
"cardinality":{"field":"token.tokenId"}
}
}
}
}
}
}
}
注意:
为了提高基数聚合的准确性,请尝试增加POST查询中的precision_threshold控制器。这是以更多内存利用为代价的。
结帐链接了解更多详情 Elasticsearch Cardinality Aggregation
宁愿建议根据要求设计此项,并且只有在准备好接受规模下的错误百分比时才会这样做。