Проблема - в коллекции уже 45М записей. Каждые несколько часов по базе бегает map-reduce и аггрегирует данные. Проблема в том что с каждым днем он это делает все медленней и медленней.
Структура исходной коллекции примерно такая:
company_id:xxx, ts:.....
company_id:xxx, ts:.....
company_id:yyy, ts:.....
company_id:xxx, ts:.....
company_id:yyy, ts:.....
Аггрегирующиай запрос приводит ее к такому:
ts:...., xxx:3,
ts....., yyy:2
и т.д. где ts - дата (без времени)
То-есть мап-редъюс бегает постоянно по огромному числу уже отработанных ts, выполняя работу которая уже была сделана. Как обычно решаются такие проблемы. Тоесть как заставить его бегать только по новым данным? Можно кончено как то запоминать последний ts на момент запуска обработчика и следующий запускать уже с фильтром {ts:{$gt:__stored_ts__}} но мне кажется это не правильно. Так как:
1 - непонтно какой ts сохранять - ts начала работы или когда работа завершена.
2 - как мержить данные в результирующей таблице. Пример. У company_id:xxx, за некий день ts: 20.02.2014 было 3, после прохождения алгоритмом у этой же xxx на этот же ts добавилось 6. Тоесть по сути в результирующей коллекции должно быть 9. Пока я вижу вариант только с map-reduce в отдельную коллекцию и запуск скрипта который обновит данные в основной сводной коллекции простым перебором значений.
А нет вариантов при вставке где-то обновлять счетчик ts: .... => xxx + 1 или ts: ... => yyy + 1 ?
Операция-то копеечная, зато сэкономит вам кучу времени
@AMar4enko Ну это можно тоже. Я пока остановился на следующей схеме.
Так как ts в результирующей таблице у меня округляется до даты (без времени) то я просто запускаю процесс мап-редьюса с такими параметрами:
var map = function(){...}
var reduce = function(k,v){...}
out = {merge:"result_collection"}
var d = new ISODate()
d.setHours(0)
d.setMinutes(0)
d.setSeconds(0)
d.setMilliseconds(0)
db.source_collection.find({ts:{$gt:d}})
по крону все это выполняется раз в 10 минут и по сути в процесс м/р попадает только сегодняшний день. А флаг merge перезаписывает в результирующей таблицы данные с одинаковыми ключами.
Вроде как работает и работает быстро.