mongodb 更新聚合中的$addToSet

fslejnso  于 2023-03-17  发布在  Go
关注(0)|答案(2)|浏览(255)

我有一个MongoDB更新聚合管道,我需要用$addToSet扩展它,因为我想向数组添加新元素,但我无法管理它以使其与聚合管道一起工作。
MongoDBPlayground:https://mongoplayground.net/p/9f_rS2QjLR _
要更新的文档:

{
    "_id": 1,
    "arr": [
      "foo",
      "bar"
    ]
  }

聚合管道:

db.collection.update({
  "_id": 1,
  
},
[
  {
    "$set": {
      "arr": {
        $addToSet: {
          "$arr": {
            $each: [
              "bar",
              "baz"
            ]
          }
        }
      }
    }
  }
])

预期产出:

{
    "_id": 1,
    "arr": [
      "foo",
      "bar",
      "baz"
    ]
  }

如果无法使用$addToSet操作符,我如何使用其他操作符手动创建相同的行为?

vc6uscn9

vc6uscn91#

1.$addToSet,带正常更新查询****(将删除重复值)

demo

db.collection.update({
  _id: 1
},
{
  $addToSet: {
    arr: "baz"
  }
})

如果要向数组中添加多个元素,请使用$each,如
demo

db.collection.update({
  _id: 1
},
{
  $addToSet: {
    arr: {
      $each: [
        "baz",
        "abc",
        "def"
      ]
    }
  }
})

2.可以将$concatArrays与聚合一起使用(不删除重复值)

demo

db.collection.aggregate([
  {
    $match: {
      _id: 1
    }
  },
  {
    $project: {
      arr: {
        $concatArrays: [
          "$arr",
          [
            "baz",
            "abc",
            "bar"  //will be duped
          ]
        ]
      }
    }
  }
])

从MongoDB 4.2开始,您可以使用聚合管道进行更新操作。对于更新操作,聚合管道可以由以下阶段组成:$addFields $set $project $unset $replaceRoot $replaceWith
因此可以使用$projectdemo

db.collection.update({
  _id: 1
},
[
  {
    $project: {
      arr: {
        $concatArrays: [
          "$arr",
          [
            "baz",
            "abc",
            "bar"  //will be duped
          ]
        ]
      }
    }
  }
])

3.可以将$setUnion与聚合一起使用(重复值将被删除)

demo

db.collection.aggregate([
  {
    $match: {
      _id: 1
    }
  },
  {
    $project: {
      arr: {
        $setUnion: [
          "$arr",
          [
            "baz",
            "abc",
            "bar"  //will not be duped
          ]
        ]
      }
    }
  }
])


demo

db.collection.update({
  _id: 1
},
[
  {
    $project: {
      arr: {
        $setUnion: [
          "$arr",
          [
            "baz",
            "abc",
            "bar"   //will not be duped
          ]
        ]
      }
    }
  }
])
vcirk6k6

vcirk6k62#

这段代码保持顺序并在数组末尾添加新项。

db.collection.updateOne({
  _id: 1
}, [{
    $set: {
      arr: {
        $concatArrays: [
          {
            $ifNull: ["$arr", []]
          },
          {
            $filter: {
              input: ['bar', 'baz'],
              as: "item",
              cond: {
                $eq: [{
                  $indexOfArray: [
                    {
                      $ifNull: ["$arr", []]
                    },
                    "$$item"
                  ]
                }, -1]
              }
            }
          }
        ]
      }
    }
  }
])

另外,请记住,$project子句将删除文档中所有它没有指定字段。

相关问题