Существует довольно запутанное и не очень эффективное решение с использованием следующего _ 1_ агрегирование.
{
"size": 0,
"query": {
"match_all": {}
},
"aggs": {
"docs_per_month": {
"date_histogram": {
"field": "created_date",
"interval": "month",
"min_doc_count": 0
},
"aggs": {
"avg_doc_per_biz_day": {
"scripted_metric": {
"init_script": "_agg.bizdays = []; _agg.allbizdays = [:]; start = new DateTime(1970, 1, 1, 0, 0); now = new DateTime(); while (start < now) { def end = start.plusMonths(1); _agg.allbizdays[start.year + '_' + start.monthOfYear] = (start.toDate()..<end.toDate()).sum {(it.day != 6 && it.day != 0) ? 1 : 0 }; start = end; }",
"map_script": "_agg.bizdays << _agg.allbizdays[doc. created_date.date.year+'_'+doc. created_date.date.monthOfYear]",
"combine_script": "_agg.allbizdays = null; doc_count = 0; for (d in _agg.bizdays){ doc_count++ }; return doc_count / _agg.bizdays[0]",
"reduce_script": "res = 0; for (a in _aggs) { res += a }; return res"
}
}
}
}
}
}
Давайте подробно рассмотрим каждый сценарий ниже.
В init_script
я создаю карту количества рабочих дней для каждого месяца с 1970 года и сохраняю ее на _agg.allbizdays
карте.
_agg.bizdays = [];
_agg.allbizdays = [:];
start = new DateTime(1970, 1, 1, 0, 0);
now = new DateTime();
while (start < now) {
def end = start.plusMonths(1);
_agg.allbizdays[start.year + '_' + start.monthOfYear] = (start.toDate()..<end.toDate()).sum {(it.day != 6 && it.day != 0) ? 1 : 0 };
start = end;
}
В map_script
я просто получаю количество дней недели для месяца каждого документа;
_agg.bizdays << _agg.allbizdays[doc.created_date.date.year + '_' + doc. created_date.date.monthOfYear];
В combine_script
я суммирую среднее количество документов для каждого шарда.
_agg.allbizdays = null;
doc_count = 0;
for (d in _agg.bizdays){ doc_count++ };
return doc_count / _agg.bizdays[0];
И, наконец, в reduce_script
я суммирую среднее количество документов для каждого узла:
res = 0;
for (a in _aggs) { res += a };
return res
Опять же, я думаю, что это довольно запутанно, и, как правильно сказал Андрей, вероятно, лучше дождаться версии 2.0, чтобы она заработала так, как должна, но пока что у вас есть это решение, если оно вам нужно.
person
Val
schedule
15.06.2015