mongodb $addToSet对象数组,如果对象不存在

piwo6bdm  于 2022-12-18  发布在  Go
关注(0)|答案(1)|浏览(104)

我有这样的文件:

{
  "_id": "accountId 1",
  "codes": [
    {
      "key": "advantageCode 1",
      "dateBegin": "01/02/2012",
      "dateEnd": "01/02/2013"
    },
    {
      "key": "advantageCode 2",
      "dateBegin": "01/02/2012",
      "dateEnd": "01/02/2013"
    }
  ]
}

我想在代码中添加一个代码,如果它不存在。我已经尝试过了:

bulkWrite([{updateOne: {
            filter: { _id: commands[0].accountId },
            update: {$addToSet: {codes: {key: commands[0].advantageCode, dateBegin: commands[0].dateBegin, dateEnd: commands[0].dateEnd}}},
            upsert: true
}}])

我的问题是对象总是被添加到集合中,即使key属性已经存在。这是正常的(因为它是另一个引用),但我想知道如何将$addToSet重定为对象的key。
我需要请求是一个批量写入,因为我收集了许多不同的请求。

rdlzhqv9

rdlzhqv91#

使用更新/聚合(从4.2+开始),您可以做得更好:

db.collection.update({
  "_id": "accountId 1"
 },
 [
 {
  $set: {
  codes: {
    $cond: [
      {
        $in: [
          "advantageCode 2",
          "$codes.key"
        ]
      },
      {
        $map: {
          input: "$codes",
          in: {
            $mergeObjects: [
              "$$this",
              {
                $cond: [
                  {
                    $eq: [
                      "$$this.key",
                      "advantageCode 2"
                    ]
                  },
                  {
                    "dateBegin": "01/02/2020",
                    "dateEnd": "01/02/2021"
                  },
                  {}
                ]
              }
            ]
          }
        }
      },
      {
        $concatArrays: [
          "$codes",
          [
            {
              "key": "advantageCode 2",
              "dateBegin": "01/02/2022",
              "dateEnd": "01/02/2023"
            }
          ]
        ]
      }
    ]
  }
 }
 }
])

解释:
更新匹配的codes.key的dateBegin和dateEnd,或者如果不匹配,则将新codes对象添加到集合中。
Playground
当然,如果您只想在密钥丢失时$addToSet,那么您可以:
Playground2
bulkWrite操作看起来如下所示:

bulkWrite([{updateOne: {
 filter: { _id: commands[0].accountId },
 update: [{ $set: { codes: { $cond: [ { $in: [commands[0].advantageCode,"$codes.key"]},{ $map: { input: "$codes",in: { $mergeObjects: [ "$$this", {}]}}},{$concatArrays: ["$codes",[{
        "key": commands[0].advantageCode , 
        "dateBegin": commands[0].dateBegin,
        "dateEnd": commands[0].dateEnd
          }
          ]
        ]
      }
    ]
   }
  }
 }
 ]
 }}])

如果在找不到accountId的情况下需要upsert文档,请选择以下选项:

db.collection.update({
 "_id": "accountId 2"
 },
 [
 {
  $set: {
  codes: {
    "$cond": [
      {
        $ne: [
          {
            $type: "$codes"
          },
          "missing"
        ]
      },
      {
        $cond: [
          {
            $in: [
              "advantageCode 3",
              "$codes.key"
            ]
          },
          {
            $map: {
              input: "$codes",
              in: {
                $mergeObjects: [
                  "$$this",
                  {}
                ]
              }
            }
          },
          {
            $concatArrays: [
              "$codes",
              [
                {
                  "key": "advantageCode 3",
                  "dateBegin": "01/02/2022",
                  "dateEnd": "01/02/2023"
                }
              ]
            ]
          }
        ]
      },
      {
        "key": "advantageCode 3",
        "dateBegin": "01/02/2022",
        "dateEnd": "01/02/2023"
      }
    ]
    }
   }
  }
  ],
  {
   upsert: true
 })


解释:
1.如果找不到accountId,请插入新文档。
1.如果找不到codes.key,请将带有新键的新对象插入codes数组。
Playground3

相关问题