У меня следующая проблема. Я индексирую документы в Elasticsearch, где каждый документ представлен списком элементов (в моем случае целые числа), длина списка может варьироваться между документами. Например, doc1: [1,2,5], doc2: [2,3,5,6] и др. c. Соответствующее поле называется items . Затем я выполняю агрегацию метри c с помощью сценария следующим образом:
metrics = es.search(index=index, body=
{"query" : {
"match_all" : {}
},
"aggs": {
"frequent_pairs": {
"scripted_metric": {
"init_script" : "state.transactions = [];",
"map_script" : "state.transactions.add([params['_source']['items']);",
"combine_script" : naive_script,
"reduce_script" : reduce_cnt
}
}
}
})
Отображение просто распределяет различные списки элементов по разным шардам. Затем мне нужно выполнить тяжелые вычисления в каждом шарде, а именно вычислить все подмножества размера 3 в каждом документе и подсчитать их количество в шарде на карте ha sh. (Я знаю, ElasticSearch не предназначен для такого рода вычислений, но он мне нужен для приложения.)
Но это работает только тогда, когда либо списки документов короткие, либо общее количество документов мало , Что происходит, так это то, что многие осколки не сообщают о результатах. Я уже увеличил пространство кучи до 8 ГБ, назначил больше шардов и увеличил значение тайм-аута:
es = Elasticsearch([{'host':'localhost','port':9200, 'timeout': 1000000, "max_retries":10, "retry_on_timeout":True}])
Это в некоторой степени улучшило результаты, но все же многие шарды не возвращают никаких результатов и точной настройки параметры не помогают. Есть ли какое-либо решение или ES не следует использовать для таких дорогих вычислений? Я использую ES 7.5.2, и я буду рад предоставить более подробную информацию по запросу.
naive_script = """
HashMap itemsets = new HashMap();
int nr_trans = 0;
for (t in state.transactions){
nr_trans += 1;
int l = t.length;
for (int i=0; i<l; i++){
for (int j = i+1; j<l; j++){
for (int k = j+1; k < l; k++){
String s = Integer.toString(t[i]) + "," + Integer.toString(t[j]) + "," + Integer.toString(t[k]) + ",";
int val = 0;
if (itemsets.containsKey(s)){
val = itemsets.get(s);
}
itemsets.put(s, val + 1);
}
}
}
}
def res = [];
res.add(itemsets);
res.add(nr_trans);
return res;//itemsets;
"""