如何使用聚合更新 mongodb 中的数组值

How to update an array value in mongodb using aggregation

我的文档看起来像这样

{ _id: ObjectId("60b114b2415731001943b17f"),
processList:[ 
    { processName: 'Wood cutting',
    createdAt: '2021-05-28T08:59:06.260Z',
    updatedAt: '2021-05-28T08:59:06.260Z',
    id: '60b0f0e9659a3b001c235300',
    endTime: '2021-07-09T22:25:57.973Z',
    isCompleted: false },
    { processName: 'Painting',
    createdAt: '2021-05-28T13:32:02.441Z',
    updatedAt: '2021-05-28T13:32:02.441Z',
    id: '60b0f0e9659a3b001c235301',
    endTime: 2021-05-28T17:05:06.067Z,
    isCompleted: true },
    {processName: 'Varnishing',
    createdAt: '2021-05-28T09:46:33.169Z',
    updatedAt: '2021-05-28T09:46:33.169Z',
    id: '60b0f0e9659a3b001c235302',
    endTime: 2021-05-28T20:05:06.067Z,
    isCompleted: false } 
],

   companyId: '60b0a2b7b0beab001a068f8c',
   customerId: '60b11289415731001943b17d',
   productName: 'Queen size bed',
   quantity: 1,
   orderStartedTime: 2021-05-28T16:05:06.067Z,
   estimatedEndTime: 2021-05-29T01:05:06.067Z,
   createdAt: 2021-05-28T16:05:06.069Z,
   updatedAt: 2021-07-09T22:20:58.019Z,
   __v: 0,
  percentageCompleted: 33.33333333333333 }

我正在尝试根据 processList 中的 id 更新 percentageCompleted 和进程列表之一的 isCompleted true。

我运行这个查询但是抛出错误

db.orders.findOneAndUpdate(
{
 _id: ObjectId('60b114b2415731001943b17f')
},
[
    {
    
    $set: {"processList.$[element].isCompleted": true} 
},
{
        multi: true,
        arrayFilters: [{ 'element.id': { $eq: "60b0f0e9659a3b001c235300" } }],
},


{
    $set: {
        percentageCompleted: {
            $multiply: [
                {
                    $divide: [{
                        $size: {
                            $filter: {
                                input: "$processList",
                                as: "process",
                                cond: { $eq: ["$$process.isCompleted", true] }
                            }
                        }
                    },
                    { $size: "$processList" }]
                }, 100
            ]
        },
    }
}
]
)

当我排除数组更新(isCompleted)时,percentageCompleted 的更新正在计算和设置。有人可以帮助我如何进行。提前致谢。

不可能。聚合仅用于 fetch/read 数据。

您必须处理来自服务器的 2 个查询。

首先使用聚合找到要更新的值。

然后再次请求更新值。

如果您希望同时有多个请求尝试更新同一文档,则此方法无效。

我们可以将更新运算符与聚合运算符混合使用,如果我们需要聚合运算符,我们会使用管道更新来更新它。

pipeline updates require MongoDB >=4.2

查询

  • map更新processList
  • 您的 $set 来自您的查询

Test code here

db.collection.update({
  "_id": "60b114b2415731001943b17f"
},
[
  {
    "$set": {
      "processList": {
        "$map": {
          "input": "$processList",
          "in": {
            "$cond": [
              {
                "$eq": [
                  "$$this.id",
                  "60b0f0e9659a3b001c235300"
                ]
              },
              {
                "$mergeObjects": [
                  "$$this",
                  {
                    "isCompleted": true
                  }
                ]
              },
              "$$this"
            ]
          }
        }
      }
    }
  },
  {
    "$set": {
      "percentageCompleted": {
        "$multiply": [
          {
            "$divide": [
              {
                "$size": {
                  "$filter": {
                    "input": "$processList",
                    "as": "process",
                    "cond": {
                      "$eq": [
                        "$$process.isCompleted",
                        true
                      ]
                    }
                  }
                }
              },
              {
                "$size": "$processList"
              }
            ]
          },
          100
        ]
      }
    }
  }
])