yas*_*eco 7 mongodb mongodb-query aggregation-framework
考虑以下文档:
{
"countries" : [
{
"country" : "France",
"cities" : [
{
"city" : "Paris",
"population" : 100
}
]
},
{
"country" : "England",
"cities" : [
{
"city" : "London",
"population" : 100
},
{
"city" : "Liverpool",
"population" : 100
}
]
}
]
}
Run Code Online (Sandbox Code Playgroud)
我想添加或更新城市(假设我们有方法upsert(country, city, population)
我们有3个案例:
$push大概$push国家对象。cities1是否可以将所有这三个操作合并到一个查询中?
顺便说一句,我了解到,$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)
Run Code Online (Sandbox Code Playgroud)
常规更新查询不会更新插入嵌套数组,我建议您在客户端执行此操作,或者如果您确实想在单个查询中执行此操作,那么您可以尝试使用从 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]
}
]
]
}
]
}
}
}]
)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1145 次 |
| 最近记录: |