数据库中有一个键为heroes的数组。
Heros: [
{
name: 'Ironman',
country: 'USA'
},
{
name: 'Shaktiman',
country: 'India'
},
{
name: 'Black Panther',
country: 'Wakanda'
}
]
,我有一个新的数组,基本上有额外的英雄:
additionalHeros = [{ name: 'Wonder woman', country: 'USA' }, { name: 'Kenshiro', country: 'Japan' }]
我想更新一个英雄的名字和国家在一个特定的索引,比如1,并用新的值替换它。之后,我必须把所有其他的英雄放到同一个查询中。执行更新查询后,预期结果将是:
At index 2 -> update name: 'Krishh', country: 'India' -> put rest of the heros
hero的db值更新为:
Heros: [
{
name: 'Ironman',
country: 'USA'
},
{
name: 'Shaktiman',
country: 'India'
},
{
name: 'Krishh',
country: 'India'
},
{ name: 'Wonder woman',
country: 'USA'
},
{ name: 'Kenshiro',
country: 'Japan'
}
]
我知道推入值的部分,但我找不到任何有效的方法来立即更新和插入
$push: { heros: { $each: additionalHeros } }
-
常规更新查询不允许在同一字段中进行2次操作,这会产生冲突错误
-
你可以使用更新与聚合管道从MongoDB 4.2开始,但我认为这种方法是不有效的,你想要一个有效的方法,
$map
循环heros
数组$indexOfArray
获取heros
数组中当前对象的索引$cond
检查上述返回的index
是否与我们的输入索引匹配,然后更新最新的值,否则返回相同的对象- 第二个
$set
阶段使用$concatArrays
操作符添加新的heros
additionalHeros = [{ name: 'Wonder woman', country: 'USA' }, { name: 'Kenshiro', country: 'Japan' }]
updateIndex = {
name: "Krishh",
country: "India"
}
index = 1
db.collection.updateOne(
{}, // your query
[{
$set: {
heros: {
$map: {
input: "$heros",
in: {
$cond: [
{
$eq: [
{
$indexOfArray: [
"$heros",
{
name: "$$this.name",
country: "$$this.country"
}
]
},
index
]
},
updateIndex,
"$$this"
]
}
}
}
}
},
{
$set: {
heros: {
$concatArrays: ["$heros", additionalHeros]
}
}
}]
)
游乐场
- 您可以执行两个单独的更新查询或bulkWrite查询
- 更新特定索引属性
db.collection.updateOne(
{}, // your query
{
$set: {
"heros.1.name": "Krishh",
"heros.1.country": "India"
}
}
)
游乐场
- push array in
heros
db.collection.updateOne(
{}, // your query
{
$push: {
heros: {
$each: [
{
name: "Wonder woman",
country: "USA"
},
{
name: "Kenshiro",
country: "Japan"
}
]
}
}
}
)
游乐场
可以让文档为
{
"_id" : "heroes",
"Heros" : [
{
"name" : "Ironman",
"country" : "USA"
},
{
"name" : "Shaktiman",
"country" : "India"
},
{
"name" : "Black Panther",
"country" : "Wakanda"
}
]
}
代码应该是
let additionalHeros = [{ name: 'Wonder woman', country: 'USA' }, { name: 'Kenshiro', country: 'Japan' }]
let index = 2;
let data = { name: 'Krishh', country: 'India' }
let updateQuery = {};
updateQuery[`Heros.${index}`] = data;
let ops = [];
ops.push(
{
updateOne: {
filter: { _id: "heroes" },
update: {
$set: updateQuery,
},
upsert: true
}
},
);
ops.push(
{
updateOne: {
filter: { _id: "heroes" },
update: {
$push: { Heros: { $each: additionalHeros } }
},
upsert: true
}
},
);
let x = await db1.bulkWrite(ops, { ordered: true, upsert: true })
那么输出将是
{
"_id" : "heroes",
"Heros" : [
{
"name" : "Ironman",
"country" : "USA"
},
{
"name" : "Shaktiman",
"country" : "India"
},
{
"name" : "Krishh",
"country" : "India"
},
{
"name" : "Wonder woman",
"country" : "USA"
},
{
"name" : "Kenshiro",
"country" : "Japan"
}
]
}