我有以下文件:
[{
"_id":1,
"name":"john",
"position":1
},
{"_id":2,
"name":"bob",
"position":2
},
{"_id":3,
"name":"tom",
"position":3
}]
在UI中,用户可以改变项目的位置(例如,将Bob移动到第一位置,john获得位置2,tom-位置3)。 有没有办法一次更新所有文件中的所有职位?
答案 0 :(得分:24)
使用MongoDB查询无法一次更新两个文档。您将始终必须在两个查询中执行此操作。您当然可以将字段的值设置为相同的值,或者使用相同的数字递增,但是您不能使用相同的查询在MongoDB中执行两个不同的更新。
答案 1 :(得分:1)
您可以使用db.collection.bulkWrite()
批量执行多项操作。自3.2
起可用。
可以不按顺序执行操作以提高性能。
答案 2 :(得分:1)
在mongodb 4.2中,您可以使用$ set运算符在更新中使用管道
由于聚合管道中有许多运算符,所以现在有很多可能的方法,尽管我提供了其中一种
exports.updateDisplayOrder = async keyValPairArr => {
try {
let data = await ContestModel.collection.update(
{ _id: { $in: keyValPairArr.map(o => o.id) } },
[{
$set: {
displayOrder: {
$let: {
vars: { obj: { $arrayElemAt: [{ $filter: { input: keyValPairArr, as: "kvpa", cond: { $eq: ["$$kvpa.id", "$_id"] } } }, 0] } },
in:"$$obj.displayOrder"
}
}
}
}],
{ runValidators: true, multi: true }
)
return data;
} catch (error) {
throw error;
}
}
示例密钥val对为[{“ id”:“ 5e7643d436963c21f14582ee”,“ displayOrder”:9},{“ id”:“ 5e7643e736963c21f14582ef”,“ displayOrder”:4}]
答案 3 :(得分:0)
由于MongoDB 4.2 update
可以接受聚合管道作为第二个参数,因此可以基于多个文档的数据进行修改。
摘录自文档:
使用文档中其他字段的值修改字段
使用以下文档创建成员集合:
db.members.insertMany([ { "_id" : 1, "member" : "abc123", "status" : "A", "points" : 2, "misc1" : "note to self: confirm status", "misc2" : "Need to activate", "lastUpdate" : ISODate("2019-01-01T00:00:00Z") }, { "_id" : 2, "member" : "xyz123", "status" : "A", "points" : 60, "misc1" : "reminder: ping me at 100pts", "misc2" : "Some random comment", "lastUpdate" : ISODate("2019-01-01T00:00:00Z") } ])
假设您希望将这些字段收集到一个新的注释字段中,而不是单独的misc1和misc2字段。以下更新操作使用聚合管道执行以下操作:
- 添加新的注释字段并设置lastUpdate字段。
- 删除集合中所有文档的misc1和misc2字段。
db.members.update( { }, [ { $set: { status: "Modified", comments: [ "$misc1", "$misc2" ], lastUpdate: "$$NOW" } }, { $unset: [ "misc1", "misc2" ] } ], { multi: true } )