如何用Ruby的Mongoid更新MongoDB文档数组内的嵌入对象
使用Ruby和Mongoid更新MongoDB数组内的嵌入对象
需求:更新指定Customer文档中,orders数组里reference_number为'12'的对象的amount值,现有文档结构如下:
{ _id: 23234342, age: 23, customer_name: 'alex', email: 'alex@gmail.com', orders: [ { reference_number: '10', amount: 2300, ordered_at: '01-01-2023 11:12:00' }, { reference_number: '12', amount: 2300, ordered_at: '01-01-2023 11:12:00' }, ] }
你尝试的代码存在两个问题:一是reference_number传了数字12(原文档是字符串'12'),二是elem_match的调用方式不符合Mongoid的链式语法。以下是正确的实现方式:
正确写法示例
写法一:直接在查询条件中指定数组元素匹配
这种方式最简洁,不需要单独调用elem_match:
Customer.where(_id: 23234342, 'orders.reference_number' => '12').update_all("$set" => {"orders.$.amount" => 4000})
写法二:使用elem_match语法
如果需要更明确的数组元素匹配逻辑,可以用elem_match,注意要嵌套在where参数中:
Customer.where(_id: 23234342, orders: { "$elemMatch" => { reference_number: '12' } }).update_all("$set" => {"orders.$.amount" => 4000}) # 或者用Mongoid的符号语法 Customer.where(_id: 23234342).where(:orders.elem_match => { reference_number: '12' }).update_all("$set" => {"orders.$.amount" => 4000})
关键注意事项
- 类型一致性:原文档中
reference_number是字符串类型,查询时必须传入字符串'12',不能用数字12,否则会匹配不到目标元素 - 更新方法选择:
update_all会更新所有匹配的文档,如果你确定只会有一个匹配的文档,也可以用update(但update_all语义更清晰) - 位置操作符
$:MongoDB的$操作符会自动定位到数组中第一个符合条件的元素,刚好满足更新指定订单的需求
内容的提问来源于stack exchange,提问作者Fahad Subzwari
相关产品推荐
相关产品推荐

