Монгоидные встраиваемые комментарии и информация пользователя, которые могут меняться

У меня есть документ List со встроенными комментариями. Наряду с комментарием пользователя в представлении я хотел бы отобразить их имя экрана и изображение профиля. Изображение профиля может измениться, а также имя экрана.

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

Модель комментария

class Comment
  include Mongoid::Document
  field :user_id
  field :username
  field :profile_pic_url
  field :content
  field :created_at, type: Date
  embedded_in :list, :inverse_of => :comments
end

Однако риск состоит в том, что данные комментариев (имя пользователя и профиль профиля) становятся устаревшими, если пользователь меняет их, если нет, например, фильтра «after_save» в модели User, который пытается обновить все экземпляры комментариев.

Любые указания по правильному дизайну? Я мог бы сделать так, чтобы комментарии не были встроены и сделали так, чтобы у пользователя было много комментариев, а в списке много комментариев, но я стараюсь играть в силах Монго.

1
добавлено
Просмотры: 2
nl ja de

2 ответы

Ваше приложение, это шаблоны доступа, масштабирование и требования к производительности. С SQL, нормализация и привязка/привязка - это ваш единственный выбор, но с MongoDB вы можете вставлять.

MongoDB обеспечивает гибкость при сопоставлении схемы с потребностями вашего приложения, при необходимости вы можете выбрать нормализацию/привязку/привязку или денормализацию/внедрение, а Mongoid упрощает выбор.

(a) Нормализация уменьшает избыточность, следуя хорошему принципу «Не повторяйте себя» (DRY). (b) Денормализация вводит избыточность, следуя распространенным практикам, таким как кеширование или мемонирование для производительности.

В целом, исходя из потребностей вашей заявки:

Требуется высокая согласованность - да: normalize/link, no: denormalize/embed

Требуется высокая читаемость - да: denormalize/embed, no: normalize/link

Требуется высокая производительность записи - да: normalize/link, no: denormalize/embed

Требуется высокое масштабирование - да: normalize/link, no: denormalize/embed

Отношения:

один-к-одному - да: denormalize/embed, no: ...

один-ко-многим - да: denormalize/embed, no: ...

многие-ко-многим - да: нормализовать/ссылку, нет: ...

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

Плохая новость заключается в том, что нет формулы, которая не требует никакой мысли. Хорошей новостью является то, что MongoDB обладает гибкостью в соответствии с вашим приложением. 10gen предлагает переговоры по дизайну схем.

2
добавлено
Я пошел с сохранением имени пользователя и изображения пользователя как части комментариев, поскольку этот подход наилучшим образом соответствовал профилю производительности, который я надеялся достичь, вставив комментарии в первую очередь.
добавлено автор aressidi, источник

Я хотел бы обратиться к пользователю вместо того, чтобы помещать каждое поле в каждый комментарий.

class User
  include Mongoid::Document
  include Mongoid::Timestamps
  field :user_id
  field :username
  field :profile_pic_url
  has_many :comments
end

class Comment
  include Mongoid::Document
  include Mongoid::Timestamps
  field :content
  belongs_to :user
  embedded_in :list, :inverse_of => :comments
end

You can find documentation for the has_many relation at http://mongoid.org/en/mongoid/docs/relations.html#has_many

Я также пошел дальше и использовал временные метки дополнительно и удалил поле created_at, которое задокументировано на http : //mongoid.org/en/mongoid/docs/extras.html#timestamps .

1
добавлено
Спасибо Николаю, это, кажется, правильный подход к работе!
добавлено автор aressidi, источник
Одна вещь, которую я заметил. Я ожидал, что я могу получить доступ к модели пользователя из комментариев. Поскольку комментарий встроен в список, Mongoid сообщает мне, что мне нужно будет хранить дополнительный внешний ключ в корневом документе (предположительно, в документе List). Вот что я пытался сделать на мой взгляд: - @ comments.each do | c | % a.pull-left = image_tag c.user.profile.image: class => 'media-object' .media-body% h4.media-heading = c.username = c.content
добавлено автор aressidi, источник