2016-10-04 2 views
1

Я нуб с ES, и я не знаю, как решить этот простой сценарий:Несколько Aggs с ElasticSearch

 
dataType value 

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

Мне нужно знать, сколько типов данных только «А» значение, сколько только есть «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" 
                        ] 
                    ] 
                ] 
            } 
        } 

Datatypes сгруппированы правильно, но мне кажется, что они разделенных на разные ведра или острые предметы, и последний шаг «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 проходит через каждый документ и добавляет тип данных в onlya если значение «A» или onlyb. Вы можете заменить второй, если с другой, если вы уверены, что вы будете или А или В

combine_script преобразует список уникальных значений, так [1,1,3,3,4] становится [1,3,4]

reduce_script получает результаты от всех осколков. Пересечение даст вам ведро с обоими значениями данных и вычитание даст вам только часть. 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()];" 

     } 
    } 
    } 
Смежные вопросы