Вопрос по оптимизации в MapReduce в MongoDB - PullRequest
3 голосов
/ 09 августа 2011

Итак, мы с другом пытаемся уменьшить карту для коллекции, в которую последовательно добавляются элементы.

В основном мы вычисляем среднее значение некоторых полей и помещаем их в коллекцию (с помощью уменьшения карты).

В этом и заключается проблема: каждый раз, когда выполняется уменьшение карты, оно проходит через ВСЕ документы. Я новичок в уменьшении карты, но, исходя из того, что я знаю, кажется, что было бы суперэффективно, если бы он только запускал преобразование карты в новых и / или измененных документах и ​​обновлял их существующей коллекцией.

Так что я был в порядке, я просто сделаю это сам. В коллекцию добавлено «обработано: ложь», и когда прогоны сокращения карты, я передаю фильтр запросов «{обработанный: ложь}», затем после прогонов сокращения карты я затем устанавливаю «{обработанный: истина}» для всех элементов. где обработано = ложь.

Вот проблема. Я беспокоюсь о крайнем случае. Что произойдет, если при уменьшении карты некоторые элементы будут добавлены в коллекцию? Они никогда не передавались в карту Reduce, и теперь после прогонов карты уменьшения их обработанный флаг устанавливается в значение true.

Что было бы замечательно, если бы вместо передачи «фильтра запросов» в mongo я мог бы передать объекту запроса «set». Тогда я могу установить для обработанного флага значение true и затем передать эти объекты.

1 Ответ

1 голос
/ 09 августа 2011

Сделай это за 3 шага.Есть 3 состояния, скажем, UNPROCESSED, MARKEDFORPROCESSING и PROCESSED, затем:

  1. db.col.update ({processingState: UNPROCESSED}, {$ set: {processingState: MARKEDFORPROCESSING}}, false, true)
  2. Запустите m / r для документов MARKEDFORPROCESSING.Они гарантированно были там при запуске m / r.
  3. db.col.update ({processingState: MARKEDFORPROCESSING}, {$ set: {processingState: PROCESSED}}, false, true)
  4. Перейдите к 1.

Это исключает ваш крайний случай, и атомарные обновления MongoDB полностью безопасны.

...