Mongoose文档更新 - 数组中选定的对象 - 使用$ in运算符

时间:2014-12-11 17:39:19

标签: mongodb mongoose

我的架构如下。

客户:{

orders: [{
     ...
    status: 'Pending'
        ...
}]

}

我有一份订单ID列表,这些订单ID已交付给客户。所以我需要将状态更改为关闭。这是我的简单要求。我有以下代码,它仅为OrderIdList中的第一个订单ID更新状态“已关闭”。

orderIdList = [“54899c0cbdde6b281e9aaa22”,“54899c28bdde6b281e9aaa23”,“54899c2abdde6b281e9aaa24”,“54899c2cbdde6b281e9aaa25”]

Customer.update({
    'orders._id': {
        $in: orderIdList
    }
}, {
    '$set': {
        'orders.$.status': 'Closed'
    }
}, {
    multi: true,
    upsert: true
}, function(err, rows) {
    console.log("error");
    console.log(err);
    console.log("rows updated");
    console.log(rows);
});

只更新了一行。对于orderId“54899c0cbdde6b281e9aaa22”

为什么不更新所有订单ID。请建议我解决方案。

提前致谢。

1 个答案:

答案 0 :(得分:0)

  

更新状态'已关闭'仅适用于中的第一个订单ID   OrderIdList。

是的,这就是位置运算符($)的工作原理。它仅更新数组中与查询条件匹配的第一项。

来自文档,

  

位置$运算符充当第一个元素的占位符   与查询文档匹配。

multi: true适用于父文档,不适用于嵌入式文档。如果此参数设置为true,则将更新具有与所需Id匹配的订单的所有文档。但位置运算符将仅更新与所有这些文档中的查询匹配的第一个子文档。

要更新所有匹配文档的所有匹配订单,目前在单个mongo更新查询中是不可能的。您需要在应用程序代码中执行逻辑。

在应用程序代码中执行此操作的一种方法:

  • 匹配包含我们订单的所有客户文档 寻找。
  • 为每个客户文档标识我们需要的订单 更新
  • 修改订单。
  • 根据客户文档_id执行更新。

示例代码:

var orderIdList = ['54899c0cbdde6b281e9aaa22'];
Customer.find({"orders._id":{$in:orderIdList }},function(err,resp){
resp.forEach(function(doc){
var orders = doc.orders;
orders.forEach(function(order){
if(orderIdList.indexOf(order._id.toString()) != -1){
order.status = 'closed';
Customer.update({"_id":doc._id},{$set:{"orders":orders}},function(err,aff,raw){
console.log("Updated: "+aff);
});}})})})