Mongodb findAndModify встроенный документ - как узнать, какой из них вы изменили?

findAndModify в mongodb это здорово, но у меня возникли небольшие проблемы, зная, какой встроенный документ я изменил

Вот пример, где Post embeds_many Comments, (Я использую Mongoid ORM, но этот вопрос является общим для любой установки MongoDB).

begin
  p = Post.asc(id).where(comments: { '$elemMatch' => {reserved: false} }).find_and_modify({'$set' => {'comments.$.reserved' => true}}, {new: true}
  # now i need to find which comment I just reserved
  c = p.comments.select{|c| c.reserved }.first
  ...
ensure
  c.update_attribute :reserved, false
end

Хорошо, этот вид работ, но если у меня есть несколько процессов, выполняющих это одновременно, мой select Можно выбрать комментарий, который был зарезервирован другим процессом (условие гонки).

Это самое близкое, что у меня есть (резервирование по идентификатору процесса):

begin
  p = Post.asc(id).where(comments: { '$elemMatch' => {reserved: nil} }).find_and_modify({'$set' => {'comments.$.reserved' => Process.pid}}, {new: true}
  # now i need to find which comment I just reserved
  c = p.comments.select{|c| c.reserved == Process.pid }.first
  ...
ensure
  c.update_attribute :reserved, nil
end

Который, кажется, работает. Это лучший способ сделать это или есть лучший шаблон?

1 ответ

Решение

Был в состоянии решить это путем генерации SecureRandom.hex и установив это во встроенном документе с find_and_modify, Затем вы можете просмотреть вложенные документы и посмотреть, у какого из них есть соответствующий гекс, чтобы увидеть, с каким вы работаете.

Другие вопросы по тегам