2016-10-04 25 views
1

多AGGS我與ES一個小白,我不知道如何解決這個簡單的場景:與ElasticSearch

 
dataType value 

    1 A 
    1 A 
    1 B 
    2 B 
    3 A 
    3 A 
    4 A 
    4 B 

我需要知道有多少數據類型只有「A」值,有多少隻'B'值,以及兩者都有。在這個例子中預期的結果將是:

Only A = 1 (dataType 3) 
Only B = 1 (dataType 2) 
Both = 2 (dataTypes 1 and 4) 

你能幫助我嗎?謝謝。

ChintanShah25嗨,非常感謝您的快速回復。我想你已經制定,但似乎不能正常工作代碼:

"Aggregations": { 
         "Datatypes": { 
             "Value": { 
             "Both": 0, 
                "Onlya": 1, 
                "OnlyB": 1 
            } 
        } 
    } 

如果我刪除「reduce_script」我可以調試,獲得:

 

    "Aggregations": { 
     "Datatypes": { 
     "Value": [ 
                    [ 
                        [ 
                            "1" 
                        ], 
                        [] 
                    ], 
                    [ 
                        [] 
                        [] 
                    ], 
                    [ 
                        [ 
                            "1" 
                        ], 
                        [ 
                            "1", 
                            "2" 
                        ] 
                    ], 
                    [ 
                        [ 
                            "4" 
                        ], 
                        [] 
                    ], 
                    [ 
                        [ 
                            "3" 
                        ], 
                        [ 
                            "4" 
                        ] 
                    ] 
                ] 
            } 
        } 

數據類型是正確的分組,但似乎他們是分成不同的桶或銳器,最後一步「reduce_script」失敗。

文檔「腳本度量標準」很差,雖然測試沒有達到預期的結果。

問候。

回答

2

我想這很棘手,可以通過scripted metric aggregation完成。我創建了一個測試索引並插入了您提供的示例數據。下面的查詢讓你想

{ 
    "query": { 
    "match_all": {} 
    }, 
    "aggs": { 
    "Datatypes": { 
     "scripted_metric": { 
     "init_script": "_agg['onlya'] = [];_agg['onlyb'] = [];", 
     "map_script": "if (doc['value'].value == \"A\") 
         { _agg.onlya.add(doc['datatype'].value) }; 
         if (doc['value'].value == \"B\") 
         { _agg.onlyb.add(doc['datatype'].value) };", 
     "combine_script": "onlya = _agg['onlya'].unique(); 
          onlyb = _agg['onlyb'].unique(); 
          return[onlya, onlyb]", 
     "reduce_script": "both_bucket=[];a_bucket=[];b_bucket=[]; 
          for(a in _aggs) 
          {both_bucket=a[0].intersect(a[1]); 
          a_bucket=a[0]-a[1]; 
          b_bucket=a[1]-a[0]}; 
          return ['Both' : both_bucket.size(), 
            'OnlyA' : a_bucket.size(), 
            'OnlyB' : b_bucket.size()];" 
     } 
    } 
    }, 
    "size": 0 
} 

結果這是輸出我得到

"aggregations": { 
     "Datatypes": { 
     "value": { 
      "Both": 2, 
      "OnlyA": 1, 
      "OnlyB": 1 
     } 
     } 
    } 

您將需要enable dynamic scripting這個工作或者把這些腳本scripts folder

期間init_script,我聲明瞭兩個變量,它們將保存數據類型的值。

map_script經過每一個文件,並增加了數據類型爲分析:定冠詞如果值是「A」或onlyb。你可以用別的替代第二,如果你確信你要麼有A或B

combine_script轉換列表中唯一值,以便[1,1,3,3,4]成爲[1,3,4]

reduce_script會從所有的碎片結果。 交叉口會給你兩個數據類型值和減法會給你只有部分。 size()爲您提供列表的長度。移除size方法以獲得匹配的數據類型值。

請通過documentation找到更多關於如何聚集所有這些工作不同階段

0

我終於得到它的工作,因爲我想要的。非常感謝您的幫助。

"aggs": { 
    "Datatypes": { 
     "scripted_metric": { 
     "init_script": "_agg['onlya'] = [];_agg['onlyb'] = [];", 
     "map_script": "valueAdd=doc['datatype'].value; if (doc['value'].value == \"a\") { _agg['onlya'].add(valueAdd) }; if (doc['value'].value == \"b\") { _agg['onlyb'].add(valueAdd) };", 
     "combine_script": "onlya = _agg['onlya'].unique();       onlyb = _agg['onlyb'].unique();       return[onlya, onlyb]", 
     "reduce_script": "a_bucket=[];b_bucket=[];for(a in _aggs){ a_bucket+=a[0]; b_bucket+=a[1];}; return ['Both' : a_bucket.intersect(b_bucket).size(), 'OnlyA' : (a_bucket-b_bucket).size(), 'OnlyB' : (b_bucket-a_bucket).size()];" 

     } 
    } 
    }