MongoDB:如何在嵌套数组中更新插入对象?

2024-06-18

考虑以下文档:

{
    "countries" : [ 
        {
            "country" : "France",
            "cities" : [ 
                {
                    "city" : "Paris",
                    "population" : 100
                }
            ]
        }, 
        {
            "country" : "England",
            "cities" : [ 
                {
                    "city" : "London",
                    "population" : 100
                }, 
                {
                    "city" : "Liverpool",
                    "population" : 100
                }
            ]
        }
    ]
}

我想添加或更新城市(假设我们有方法upsert(country, city, population)

我们有3个案例:

  1. 国家和城市已经存在 - 这只是更新(替换城市对象)
  2. 国家存在但城市不存在 - 只需要$push大概
  3. 国家和城市不存在 - 需要准备和$push国家对象cities大小数组1其中包含新城市。

是否可以将所有这三个操作合并到一个查询中?

顺便一提, 我了解到$addToSet但根据我的理解,它会比较所有对象的键,在我看来,它不会起作用,因为我也有cities这是一个数组。

使用 ArrayFilters 进行更新相当简单:

q = {"_id":"1"}

update = {
    "$set": {
        "countries.$[i].cities.$[j].population": 200,

    }
} 

options = {
    "arrayFilters": [
        {
            "i.country": "France"
        },
        {
            "j.city": "Paris",
        },
    ],
}

db.collection.updateOne(q, update, options)

常规更新查询不会更新插入嵌套数组,我建议您在客户端执行此操作,或者如果您确实想在单个查询中执行此操作,那么您可以尝试使用聚合管道更新 https://docs.mongodb.com/manual/tutorial/update-documents-with-aggregation-pipeline/从 MongoDB 4.2 开始,在聚合管道中这是一个漫长的过程,

  • $map迭代数组的循环
  • $mergeObjects将当前对象与更新的字段合并
  • $cond检查 if-else 条件
  • $concatArrays连接 2 个数组
var country = "France";
var city = {
  city: "Paris",
  population: 100
};

db.collection.update({},
 [{
    $set: {
      countries: {
        $cond: [
          { $in: [country, "$countries.country"] },
          {
            $map: {
              input: "$countries",
              in: {
                $cond: [
                  { $eq: [country, "$$this.country"] },
                  {
                    $mergeObjects: [
                      "$$this",
                      {
                        $cond: [
                          { $in: [city.city, "$$this.cities.city"] },
                          {
                            cities: {
                              $map: {
                                input: "$$this.cities",
                                in: {
                                  $cond: [
                                    { $eq: [city.city, "$$this.city"] },
                                    city,
                                    "$$this"
                                  ]
                                }
                              }
                            }
                          },
                          {
                            cities: {
                              $concatArrays: ["$$this.cities", [city]]
                            }
                          }
                        ]
                      }
                    ]
                  },
                  "$$this"
                ]
              }
            }
          },
          {
            $concatArrays: [
              "$countries",
              [
                {
                  country: country,
                  cities: [city]
                }
              ]
            ]
          }
        ]
      }
    }
  }]
)

操场 https://mongoplayground.net/p/0zy8rOKlQ4d

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MongoDB:如何在嵌套数组中更新插入对象? 的相关文章

随机推荐