如何在Mongo / Mongomatic中进行原子更新?

时间:2012-10-04 19:09:17

标签: ruby mongodb

使用Mongomatic的原子'$ set'运算符,我很难搞清楚如何更新MongoDB文档。我很确定这是Mongo的标准/更新语言我遇到麻烦,而不是Mongomatic,但我愿意被证明是错误的。

指向带有独立可运行脚本的要点的链接位于:https://gist.github.com/3835672

我首先创建一个如下所示的文档:

{"videos":[{"video_id":"video1"},{"video_id":"video2"}],"_id":{"$oid": "506ddd53a114604ce3000001"}}

我可以使用Mongomatic实例化的模型来获取该文档:

video_group = VideoGroup.find_one('videos.video_id' => 'video1')

然后我试图通过这样做来设置'views'字段:

video_group.update!({ 'videos.video_id' => 'video1' }, '$set' => { 'videos.$.views' => 123 })

这就是Mongo爆炸的地方,出现以下错误:

can't append to array using string field name [$]

我知道这是StackOverflow上一个非常常见的问题。我一般都明白问题在于位置操作员没有得到任何匹配。但即使阅读了几十篇回复,我仍然无法弄清楚如何以一种有效的方式表达这种说法。

我刚刚开始使用错误的数据结构吗?

1 个答案:

答案 0 :(得分:1)

事实上,它是一个mongomatic问题。您需要传递基础mongo ruby​​驱动程序选项{:multi => true},以及包含发送到mongodb的更新的特定_id的条件,而不是作为可选参数的一部分。看起来像是mongomatic中的一个bug。以下是我用来查找它的ruby调试器脚本:https://gist.github.com/3836797

请注意,我对您发布的文件进行了更改,在第41行之前添加了行debugger,并将第42-44行更改为:

video_group.update!({ 'videos.video_id' => 'video1', :multi => true }, '$set' => {
  'videos.$.views' => 123,
})