2013-08-14 2 views
0

У меня есть простой сценарий двух объектов: post; удары (т.е. вверх).Поддержание общего количества наборов в другой коллекции

Пример поста:

{_id: 'happy_days', 'title': 'Happy days', text: '...', bumps: 2} 

Пример шишка:

{_id: {user: 'jimmy', post: 'happy_days'}} 
{_id: {user: 'hans', post: 'happy_days'}} 

Вопрос: как я могу поддерживать правильный bumps подсчет в должности при всех обстоятельствах (и неудач)?

Метод, который я придумал до сих пор:

  • Чтобы шишка, upsert и проверить на существование. Только если вставлено, увеличьте значение bumps.
  • Чтобы удалить, удалить и проверить на существование. Только если удалено, уменьшите bumps count.

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

ответ

1

Я предлагаю вам придерживаться того, что у вас уже есть. Хуже того, что может произойти, если между вашими двумя операциями возникает проблема с отказоустойчивостью/связью, вы ошибаетесь. И что? Это не конец света, и никто не будет заботиться слишком много, если количество ударов составляет 812 или 813. Вы всегда можете воссоздать счет в любом случае, проверив, сколько ударов у вас есть для каждого сообщения, выполнив запрос агрегации если что-то пошло не так. Обрежьте возможную последовательность!

+0

Одна замечательная вещь, которая пришла ко мне вчера, заключалась в использовании лимитов в подписке оператора $ inc, чтобы остановить счетчики от истечения срока действия ниже 0 и т. Д. И т. Д., К сожалению, он был классифицирован как часть большего и более ... unweidly JIRA условного выполнение запроса. Хотя я все еще думаю, что это была хорошая идея – Sammaye

0

Поскольку MongoDB еще не поддерживает триггеры (https://jira.mongodb.org/browse/SERVER-124), вы должны сделать это по-крупному с логикой приложения.

В качестве краткого примера:

db.follower.insert({fromId:u,toId:c}); 
db.user.update({_id:u},{$inc:{totalFollowing:1}}); 
db.user.update({_id:c},{$inc:{totalFollowers:1}}); 

Да, это не атомная и т.д. и т.п. Однако это способ сделать это. На самом деле многие обновления счетчики, как это, будь то в MongoDB или нет.

+0

Я уже делаю это. – Mansour

1

В качестве альтернативы обновлению данных в нескольких местах (которые, по мнению читателей, будут, вероятно, лучшими, но, как вы заметили, будут усложнять обновления), может быть стоит рассмотреть вопрос о сохранении uid из рему в массиве (здесь называется bump_uids) непосредственно в сообщении, и просто подсчитывайте удары, когда это необходимо, с использованием агрегатной структуры;

> db.test.aggregate([ { $match: { _id:'happy_days' } }, 
         { $project: { bump_uids: 1 } }, 
         { $unwind: '$bump_uids' }, 
         { $group: {_id:'$_id', bumps: { $sum:1 } } } ]) 

>>> { "result" : [ { "_id" : "happy_days", "bumps" : 3 } ], "ok" : 1 } 
+0

Удары для сообщения могут вырасти до множества тысяч элементов. Устранение проблем с пространством (т. Е. Может легко ударить 16 МБ с одного предела документа), не уверен, насколько эффективен агрегат op на даже сотнях элементов. – Mansour

Смежные вопросы