Модификаторы MongoDB / MongoMapper для встроенных документов - PullRequest
1 голос
/ 28 июня 2011

Нужна помощь в использовании атомарных модификаторов во встроенном документе.

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

Коллекция сообщений

{
  "_id" : ObjectId("blah"),
  "title" : "Some title",
  "comments" : [
    {
      "_id" : ObjectId("bleh"),
      "text" : "Some comment text",
      "score" : 0,
      "voters" : []
    }
  ]
}

Что я собираюсь сделать с MongoMapper / MongoDB, так это выполнить атомарное обновление определенного комментария в почтовом документе.

Что-то вроде:

class Comment
  include MongoMapper::EmbeddedDocument

  # Other stuff...

  # For the current comment that doesn't have the current user voting, increment the vote score and add that user to the voters array so they can't vote again
  def upvote!(user_id)
    collection.update({"comments._id" => post_id, "comments.voters" => {"$ne" => user_id}}, 
      {"$inc" => {"comments.score" => 1}, "$push" => {"comments.voters" => user_id}})
  end
end

Это в основном то, что у меня сейчас, и оно вообще не работает (ничего не обновляется). В идеале, я также хотел бы перезагрузить документ / внедренный документ, но кажется, что не может быть способа сделать это, используя встроенный документ MongoMapper. Есть идеи, что я делаю не так?

1 Ответ

2 голосов
/ 02 июля 2011

Получил это работает для всех, кто заинтересован.Две вещи, которые мне не хватало

  1. Использование $elemMatch для поиска объектов в массиве, который должен удовлетворять двум условиям (например, _id = "" И избиратели НЕ содержат user_id)
  2. Использование оператора $ в операциях $inc и $push, чтобы убедиться, что я изменяю конкретный объект, на который ссылается мой запрос.

def upvote!(user_id)
  # Use the Ruby Mongo driver to make a direct call to collection.update
  collection.update(
    {
      'meanings' => {
        '$elemMatch' => {
          '_id' => self.id,
          'voters' => {'$ne' => user_id}
        }
      }
    },
    {
      '$inc' => { 'meanings.$.votes' => 1 },
      '$push' => { 'meanings.$.voters' => user_id }
    })
end
...