Запрос непосредственно по результатам MongoDB mapreduce против обновления оригинальной коллекции - PullRequest
3 голосов
/ 01 февраля 2012

У меня есть задание mapreduce, которое запускает коллекцию постов и вычисляет популярность для каждого поста. Mapreduce выводит коллекцию с post_id и популярностью для каждого поста. Приложение должно иметь возможность сортировать сообщения по популярности. Есть миллионы сообщений, и эти популярности обновляются каждые 10 минут. Я могу придумать два метода:

Метод 1

  1. Сохранить индекс в поле популярности таблицы сообщений.
  2. Запустите mapreduce для таблицы сообщений (это заменит все предыдущие результаты mapreduce)
  3. Прокручивать каждую строку в наборе результатов mapreduce и индивидуально обновлять популярность соответствующего сообщения в таблице сообщений
  4. Запрос непосредственно к таблице сообщений для сортировки сообщений по популярности.

Метод 2

  1. Запустить mapreduce для таблицы сообщений (это заменит предыдущие результаты mapreduce)
  2. Добавление индекса в поле популярности в результирующей коллекции mapreduce
  3. Когда приложению нужны публикации, сначала запросите коллекцию результатов mapreduce, чтобы получить отсортированные значения post_ids, а затем запросите коллекцию публикаций, чтобы получить фактические данные записи

Вопросы

  1. Метод 1 должен поддерживать индекс популярности в таблице сообщений. Также потребуется обновлять миллионы (в таблице записей миллионы строк) популярности по отдельности каждые 10 минут или около того. Он будет обновлять только те сообщения, которые изменили популярность, но это все еще много обновлений в коллекции с парой индексов. В этой коллекции также будет много прочтений. Это масштабируемое?
  2. Для метода 2 можно ли преобразовать коллекцию публикаций в карту, чтобы создать новую коллекцию популярности, немедленно создать индекс для нее и запросить ее?
  3. Существуют ли какие-либо проблемы с параллелизмом для вопроса № 2, при условии, что приложение будет запрашивать, чтобы коллекция популярностей по мере ее обновления картой уменьшалась и переиндексировалась.
  4. Если mapreduce заменяет коллекцию популярностей, нужно ли мне каждый раз вручную создавать новый индекс, или Монго будет знать, чтобы сохранить индекс в поле популярности. В основном, как индексы работают с коллекциями результатов mapreduce.
  5. Есть какой-нибудь твик или другой метод, который я мог бы использовать для этого?

Спасибо за любую помощь!

1 Ответ

7 голосов
/ 02 февраля 2012

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

Можно ли добавить поле «популярность» к каждому документу «публикация», и ваше приложение будет увеличивать его каждый раз, когда каждое сообщение просматривается, нажимается, голосуется или как вы измеряете популярность?Затем вы можете проиндексировать поле популярности, и поиск сообщений по популярности будет молниеносным.

Если простое увеличение поля «популярность» не является опцией, и необходимо выполнить операцию MapReduce, попытайтесь не допустить, чтобы он просматривал все документы в коллекции.Вы обнаружите, что это становится непомерно медленным по мере роста вашей коллекции.Похоже, ваша коллекция уже довольно большая.

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

Документация по инкрементным операциям mapReduce находится здесь: http://www.mongodb.org/display/DOCS/MapReduce#MapReduce-IncrementalMapreduce

Интеграция новых результатов со старыми объясняется в разделе «Параметры вывода».

Я понимаю,что мой совет до сих пор был довольно общим, поэтому я попытаюсь ответить на ваши вопросы сейчас:

1) Как обсуждалось выше, если ваша операция MapReduce должна читать каждый отдельный документ, это не будет хорошо масштабироваться.
2) Операция MapReduce выводит только коллекцию.Создание индекса и запрос этой коллекции должны быть выполнены программно.3) Если существует один процесс, который запрашивает коллекцию в то же время, что другой обновляет ее, тогда запрос может вернуть документ до его обновления.Короткий ответ: «да» 4) Если коллекция отброшена, то индексы придется перестраивать.Если документы в коллекции удаляются, но сама коллекция не удаляется, то индексы сохраняются.В случае запуска MapReduce с параметром {out: {replace: "output"}} индекс (ex) будет сохраняться и его не нужно будет создавать заново.
5) Как указано выше, если возможнобыло бы предпочтительнее добавить другое поле в вашу коллекцию "posts" и обновить его, вместо того чтобы выполнять так много операций MapReduce.

Надеюсь, я смог предоставить вам некоторые дополнительные факторы, которые следует учитывать при создании приложения.В конечном счете, важно помнить, что каждое приложение уникально, и поэтому для окончательного доказательства того, какой путь «лучший», вам придется поэкспериментировать со всеми различными вариантами и решить для себя, какой способ наиболее эффективен.Удачи!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...