ElasticSearch中唯一嵌套文档的计数

时间:2017-06-18 06:15:32

标签: elasticsearch nosql

问题域已经有了显示许多令牌的信息亭。令牌仅由一个发行者发行,并且可以存在于多个售货亭上。自助服务终端逻辑根据该自助服务终端上存在的令牌接受/拒绝用户。

我们的弹性映射是:

"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
            }
         ]

如果没有,映射出错了哪里?我觉得这不是一个不寻常的映射。请注意,为了简洁起见,我已经截断了此处发布的映射,我们在令牌下进一步嵌套了级别。这些额外的嵌套级别带有特定于令牌及其父信息亭的字段。

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"}
                   }
               }
            }
         }
      }
   }
}

注意:

  1. elasticsearch中的基数聚合具有与之关联的错误率,因为它使用HyperLogLog近似技术来计算存储桶中的唯一字段值。随着系统中令牌数量的增加,相同的错误率会增加。 / LI>
  2. 在索引kiosk1文档时,令牌应该是一个向量/数组,以确保在索引时没有做错任何事。
  3. 为了提高基数聚合的准确性,请尝试增加POST查询中的precision_threshold控制器。这是以更多内存利用为代价的。

    结帐链接了解更多详情 Elasticsearch Cardinality Aggregation

    宁愿建议根据要求设计此项,并且只有在准备好接受规模下的错误百分比时才会这样做。