MongoDB + NoRM- Параллелизм и коллекции - PullRequest
1 голос
/ 18 февраля 2011

Допустим, у нас есть следующая структура документа:

class BlogPost
{
   [MongoIdentifier]
   public Guid Id{get;set;}
   public string Body{get;set;}
   ....
}

class Comment
{
   [MongoIdentifier]
   public Guid Id{get;set;}
   public string Body {get;set;}
}

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

если у Post есть коллекция комментариев, у меня могут возникнуть проблемы с параллелизмом, не так ли?

А размещение атрибута типа FK в Comment кажется слишком реляционным, или?

Ответы [ 4 ]

4 голосов
/ 18 февраля 2011

У вас обычно есть два варианта: 1. Объединить комментарии в документе публикации или 2. Моделировать публикацию и комментарий как документы.

Если вы агрегируете комментарии, вы должны либо: a) ввести номер редакции в сообщении, что позволит вам определять условия гонки и реализовать обработку оптимистичного параллелизма, либо b) добавлять новые комментарии с модификатором MongoDB - например, что-то вроде

var posts = mongo.GetCollection<Post>();
var crit = new { Id = postId };
var mod = new { Comments = M.Push(new Comment(...)) };

posts.Update(crit, mod, false, false);

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

На мой взгляд, (1), безусловно, является наиболее интересным вариантом, поскольку он моделирует сообщение как агрегированный объект, который является именно тем, чем он является, когда вы надеваете очки OO :). Это определенно ориентированный на документы подход, тогда как (2) напоминает плоскую структуру реляционной базы данных.

2 голосов
/ 18 февраля 2011

Это один из канонических примеров NoSQL. Стандартный метод для этого - хранить Comments как массив объектов внутри BlogPost.

.

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

Для чего-то вроде "добавить этот комментарий к сообщению" , вы обычно используете команду $push, которая добавляет комментарий к сообщению.

Я вижу, что вы используете драйверы "NoRM". Похоже, они поддерживают атомарные команды, о чем свидетельствует их тестами . Фактически, их тесты выполняют «толкать этот комментарий к сообщению в блоге» .

0 голосов
/ 18 февраля 2011

Я создал тестовое приложение, которое порождает 1000 одновременных потоков, добавляя «Комментарии» к одной и той же «Посте», в результате многие комментарии теряются.

Таким образом, MongoDB обрабатывает дочерние коллекции как одно значение, по умолчанию изменения не объединяются.

Если у меня есть коллекция комментариев к сообщению, то у меня возникают проблемы с параллелизмом, когда два или более пользователей добавляют комментарии одновременно (маловероятно, но возможно)

Так можно ли добавить комментарий в коллекцию post.comments без обновления всего объекта post?

0 голосов
/ 18 февраля 2011

Они как бы дают пример того, как вы смоделировали бы это на странице MongoDB при вставке - я думаю, вы хотите, чтобы коллекция комментариев была представлена ​​как свойство вашего сообщения.Вы добавили бы комментарии к данной сущности Post, и это избавило бы от привязки сущности Comment к ее родительской сущности Post, что, как вы вправе сомневаться, имеет смысл в СУБД, но не так много в NoSQL.решение.

Что касается параллелизма, если вы не доверяете Mongo, чтобы справиться с этим за вас, вероятно, это большой намек на то, что вам не следует создавать приложение поверх него.

...