2013-02-02 51 views
1

findAndModify在mongodb中是很棒的,但是我知道我修改了哪个嵌入式文档,有点麻烦。Mongodb findAndModify嵌入式文档 - 你怎么知道你修改了哪一个?

这里是一个例子,其中一个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可以选择的评价是另一个进程已保留(竞争状态)。

这是最接近我现在(通过进程ID保留):

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

我不太明白他们如何成为竞争条件 - findAndModify是原子。你可以发布一个示例文件 - 也许你会更加清楚你担心的情况。 –

+0

@BrianArmstrong是否面临竞争条件或它的假设,因为Asya说findAndModify是和原子操作 – Viren

回答

0

通过生成SecureRandom.hex并在find_and_modify上将其设置在嵌入式文档上,可以解决该问题。然后,您可以遍历嵌入的文档并查看哪一个具有您的匹配十六进制,以查看您正在使用哪一个。

相关问题