【问题标题】:How to update_all (with a where clause) for many embedded documents with Mongoid?如何使用 Mongoid 为许多嵌入式文档更新_all(带有 where 子句)?
【发布时间】:2012-03-01 08:21:45
【问题描述】:

我有一个 Item 类和一个 Comment 类。项目有许多嵌入的 cmets。

评论还存储了用户的用户名,所以如果用户更改了用户名,我想更新他们所有的 cmets。

我想做这样的事情(显然不行):

Item.where('comments.username' => 'elvis33').update_all('comments.username' => 'elvis')

我该怎么做?

【问题讨论】:

    标签: ruby-on-rails mongodb mongoid


    【解决方案1】:

    $ positional operator 具有限制only applies to the first matched item in the queryJira 中有一个关于该问题的未解决问题(如果您确实需要该功能,请投票)

    因此,除了检索 cmets 集合并通过循环更新所有 cmets 之外,我们别无选择。

    items = Item.only(:comments).where('comments.username' => 'elvis33')
    items.each do |item|
        item.comments.select {|com| com.username == 'elvis33'}.each do |comment|
           comment.username = 'elvis'
        end
    item.save
    end
    

    上面的代码用所有修改过的评论用户名更新每个项目一次。我没有测试过代码。

    【讨论】:

    • 感谢您提供信息和代码 RameshVel。除了.only(:comments) 子句外,我已经将它与您的代码一起使用了;我想知道这是不是因为 cmets 是嵌套文档。无论如何,您的答案似乎是最好的方法,直到它们增强 $ 位置运算符。
    【解决方案2】:

    由于用户名实际上是嵌入数组文档的一部分,因此您必须像这样使用positional operator

    Item.where('cmets.username' => 'elvis33').update_all('cmets.$.username' => 'elvis')

    【讨论】:

    • 感谢您的回答,但这不起作用。来自文档:目前 $ 运算符仅适用于查询中的 first 匹配项。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-04-02
    • 1970-01-01
    • 1970-01-01
    • 2014-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多