【问题标题】:How to update multiple documents efficiently based on the value of nested property?如何根据嵌套属性的值有效地更新多个文档?
【发布时间】:2022-01-15 19:03:49
【问题描述】:

好的,所以我需要根据其嵌套属性值的值更新文档。假设我有这个文件:

{
     "_id": "61e3050a465c380aec9f56a1",
     "name": "John Doe",
     "status": "pending",
     "payment": [
             {
                  "status": "completed"
             }, 
             {
                  "status": "completed"
             }
     ]
}

我需要找到所有payment.statuscompleted 的文档,当找到文档时,我需要更新外部status 以完成。

我可以在多个查询中执行此操作并过滤掉已完成的查询,但它会根据我认为效率不高的文档数量进行大量查询。所以我想的是,如果有办法在一个查询中做到这一点,可能是Aggregate

这是我的实现:

let orders          = await Orders.find( {} ).populate( 'payments' );
let completedOrders = orders.filter( ( order ) => order.payments.every( ( payment ) => payment.status === 'completed' ) );

    if ( completedOrders.length !== 0 ) {
        for ( let order of completedOrders ) {
             await Orders.findByIdAndUpdate( order._id, { "status": "completed" } );
        }
    }

【问题讨论】:

    标签: javascript node.js mongodb express mongoose


    【解决方案1】:

    您可以使用聚合管道进行更新。使用$map 创建一个布尔数组来指示payment.status 是否“完成”。然后使用$allElementsTrue$cond 有条件地更新外部status 字段。

    db.collection.update({},
    [
      {
        "$addFields": {
          "status": {
            "$cond": {
              "if": {
                "$allElementsTrue": {
                  "$map": {
                    "input": "$payment.status",
                    "as": "s",
                    "in": {
                      $eq: [
                        "$$s",
                        "completed"
                      ]
                    }
                  }
                }
              },
              "then": "completed",
              "else": "$status"
            }
          }
        }
      }
    ])
    

    这是Mongo playground 供您参考。

    【讨论】:

      猜你喜欢
      • 2021-05-21
      • 2020-12-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多