【问题标题】:Mongoid push with upsert带有 upsert 的 Mongoid 推送
【发布时间】:2026-01-20 22:20:04
【问题描述】:

我有模型用户:

class User
  field :username, type: String
  embeds_many :products
end

class Product
  field :name, type: String
  embedded_in :user
end

我想要一个单一的操作:

  • 插入用户
  • 在用户已经存在的情况下更新用户(我可以通过 upsert 轻松完成)
  • 推产品

这适用于更新插入:

User.new(username: 'Hello').upsert

问题是这将删除嵌入的产品(未指定产品属性)。

我可以要求 mongoid 跳过设置数组为空吗? 我可以要求mongoid在产品数组的末尾推送新产品吗? 像这样的:

User.new(username: 'Hello').push(products: [Product.new(name: 'Screen')]).upsert

【问题讨论】:

    标签: ruby mongoid mongodb-query upsert


    【解决方案1】:

    最后我手动编写了以下查询:

    User.mongo_client[:users].update_one({username: 'Hello'}, 
                                         {"$set" => {first_name: 'Jim', last_name: 'Jones'},
                                          "$pushAll" => [products: [{name: 'Screen'}, {name: 'Keyboard'}]
                                         },
                                         upsert: true)
    

    地点:

    • $set - 是我们要为给定文档设置的参数
    • $pushAll - 当您使用 $push 时,您只能指定一个元素,$pushAll 允许您附加多个元素(当您只指定一个时,它的行为类似于 $push)
    • upsert - 将在 mongodb 中执行插入/更新魔法

    在第二个散列中你还可以指定 $inc、$dec、$pop、$set 等...这非常有用。

    【讨论】: