2017-06-18 79 views
0

問題域具有許多令牌顯示在其上的信息亭。令牌僅由一個發佈者發佈,並且可以存在於多個信息亭中。信息亭邏輯根據該信息亭中存在的令牌接受/拒絕用戶。ElasticSearch中唯一嵌套文檔的計數

我們的彈性映射是這樣的:

"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

您可以更改您的查詢像這樣

{ 
    "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近似技術來計算桶中唯一的字段值。因此,隨着系統中令牌數量的增加,同樣的錯誤率也會增加。
  2. 索引kiosk1文檔時,令牌應該是一個向量/數組,以確保索引時您沒有做錯任何事情。

爲了提高基數聚合的準確性,請嘗試增加POST查詢中的precision_threshold控制器。這是以更多內存利用爲代價的。

結帳鏈接,進一步的細節 Elasticsearch Cardinality Aggregation

寧願建議此基礎上的要求,只是如果你準備在規模時接受錯誤的百分比設計。

+0

謝謝。這有幫助,但正如你指出的那樣,它是近似的,對於我們需要確切結果的場景是不可用的。 – Sau

+0

它在許多用例中的準確性和超快速度。 但是當系統中的唯一token.tokenId超過幾十萬時,不會推薦。 –

相關問題