группа elasticsearch каждые X значений

Используя elasticsearch, я запрашиваю определенное поле. Есть ли способ агрегировать все значения X?

Например, допустим, я запрашиваю 10 документов для поля «myField», возвращая 10 значений,

1, 4, 2, 4, 5, 3, 3, 2, 1, 4.

Есть ли способ агрегировать так, чтобы каждые 2 значения усреднялись, что дает

2.5, 3, 4, 2.5, 2.5 ?


person maia    schedule 23.11.2015    source источник
comment
Это интересное требование... Имеет ли значение, в каком порядке усредняются значения? Вы можете получить их в разных порядках, что изменит каждое среднее значение. Я не уверен, что есть способ сделать это, но есть ли причина, по которой вы не будете делать это на стороне приложения?   -  person fabianvf    schedule 23.11.2015
comment
Да, я бы заказал значения заранее. Я мог бы сделать это на стороне приложения, да, но в целях масштабируемости мне было интересно, можно ли это сделать с помощью elasticsearch. Со временем у меня могут быть миллионы документов для объединения.   -  person maia    schedule 23.11.2015
comment
Я думаю, вы могли бы настроить это с помощью скриптовой агрегации метрик, но это был бы полный взлом. Не уверен в повторяемости.   -  person Sloan Ahrens    schedule 24.11.2015
comment
Агрегирование метрик по сценарию с использованием elasticsearch или на стороне приложения? т.е. в какой момент появится эта агрегация и как она будет выглядеть, @SloanAhrens?   -  person maia    schedule 24.11.2015
comment
Посмотрим, смогу ли я привести пример.   -  person Sloan Ahrens    schedule 24.11.2015


Ответы (1)


Вы можете делать интересные и, возможно, нежелательные вещи с помощью объединение показателей по сценарию. Они позволяют вам определять сценарии уменьшения карты, которые работают с вашими документами. Конечно, вы можете навлечь на себя неприятности.

Но просто чтобы посмотреть, смогу ли я это сделать, я создал простой индекс с одним осколком с данными, которые вы предоставили:

PUT /test_index
{"settings": {"number_of_shards": 1}}

POST /test_index/doc/_bulk
{"index":{"_id":1}}
{"num":1}
{"index":{"_id":2}}
{"num":4}
{"index":{"_id":3}}
{"num":2}
{"index":{"_id":4}}
{"num":4}
{"index":{"_id":5}}
{"num":5}
{"index":{"_id":6}}
{"num":3}
{"index":{"_id":7}}
{"num":3}
{"index":{"_id":8}}
{"num":2}
{"index":{"_id":9}}
{"num":1}
{"index":{"_id":10}}
{"num":4}

Затем я могу усреднить каждые два документа следующим образом:

POST /test_index/_search
{
    "size": 0,
    "aggs": {
        "profit": {
            "scripted_metric": {
                "init_script" : "_agg['nums'] = []; _agg['avgs'] = [];",
                "map_script" : "_agg.nums.add(doc['num'].value); if(_agg.nums.size() == 2){ _agg.avgs.add((_agg.nums[0] + _agg.nums[1])/2.0); _agg['nums'] = [];}", 
                "combine_script" : "return _agg.avgs",
                "reduce_script" : "return _aggs"
            }
        }
    }
}
...
{
   "took": 2,
   "timed_out": false,
   "_shards": {
      "total": 1,
      "successful": 1,
      "failed": 0
   },
   "hits": {
      "total": 10,
      "max_score": 0,
      "hits": []
   },
   "aggregations": {
      "profit": {
         "value": [
            [
               2.5,
               3,
               4,
               2.5,
               2.5
            ]
         ]
      }
   }
}

Кажется, он не соблюдает порядок сортировки в запросе, хотя, насколько я могу судить, результат детерминирован.

То, что я сделал здесь, работает только с одним осколком; вы, вероятно, могли бы как-то обобщить его, если бы хотели возиться с ним достаточно долго.

Кроме того, большой отказ от ответственности: делать это в производственной среде может быть плохой идеей. Вы хотели бы сначала протестировать такие вещи на небольших наборах данных, прежде чем вы можете привести к сбою кластера из-за ошибок нехватки памяти. Также используйте сценарии только в том случае, если ваш кластер не открыт для большого плохого Интернета.

Вот некоторый код, который я использовал, чтобы поиграть с ним:

http://sense.qbox.io/gist/c31f089e63200127fd9ca09992004db8bb11b890

person Sloan Ahrens    schedule 24.11.2015
comment
Вау, спасибо, что уделили этому немного времени! К сожалению, я думаю, что из-за упомянутых вами проблем (работа только с одним осколком и несоблюдение порядка сортировки) мне придется сделать это на стороне приложения. Надеюсь, это решение поможет мне или кому-то еще в будущем! - person maia; 25.11.2015