首页 > 解决方案 > Mongoose - 更新数组中的最后一个元素(使用聚合器更新文档)

问题描述

我的问题以此为基础:仅获取数组 mongoose 的最后一个元素。但是,我正在使用 Mongoose,并且还想更新数组最后一个元素中的字段,而不仅仅是检索它。

如何修改rounds数组中的最后一个元素/对象以从更改status: startedstatus: terminated

要修改的文件

{
    "_id" : "8844d3f2d25f45df8105db1ab058d7d6",
    "rounds" : [ 
        { "status" : "offline" },
        { "status" : "paused" },
        { "status" : "started" }
    ],
    "updatedAt" : ISODate("2020-07-05T21:21:58.823Z")
}

似乎使用负索引会使这变得容易,允许修改 n-1 元素。我看到很多问题都提到了聚合,但没有一个会修改基础数据。我想将聚合与更新文档结合起来。

是否可以使用$set负索引?

标签: node.jsmongodbmongoose

解决方案


从 v4.2 开始,MongoDB 没有直接的方法来按索引更新数组元素。

但是从 v4.2 开始,您可以使用带有聚合管道的更新,它允许您基于当前数组构造一个新数组并替换当前数组。

您可以构造一个新数组,而不是修改最后一个元素,该数组由第一个顶部n - 1元素与一个新元素组合而成{ status: "terminated" }

您可以通过使用$slice获取顶部n - 1元素并使用与新元素结合来实现此目的$concatArrays

这假设元素仅包含status您要更新的字段包含多个字段的数组元素的字段,您需要使用将更新的字段与当前元素合并$mergeObjects

Model.updateOne({ // or updateMany with your condition
  _id: "8844d3f2d25f45df8105db1ab058d7d6"
}, [{
  $set: {
    rounds: {
      $concatArrays: [ // combine arrays
        {
          $slice: [ // get the top n - 1 elements
            "$rounds",
            { $subtract: [{ $size: "$rounds" }, 1] }
          ]
        },,
        [{ status: "terminated" }] // a new element to replace the last element
      ]
    }
  }
}])

推荐阅读