有效的方式来修改对象的数组通过索引和在mongodb插入新的对象在同一数组的对象?



数据库中有一个键为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 } }
  1. 常规更新查询不允许在同一字段中进行2次操作,这会产生冲突错误

  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]
}
}
}]
)

游乐场

  1. 您可以执行两个单独的更新查询或bulkWrite查询
  • 更新特定索引属性
db.collection.updateOne(
{}, // your query
{
$set: {
"heros.1.name": "Krishh",
"heros.1.country": "India"
}
}
)

游乐场

  • push array inheros
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"
}
]
}

最新更新