如何在MongoDB中基于id合并复杂对象数组?
MongoDB 基于id合并数组的单更新查询方案
你可以使用MongoDB的聚合管道式更新(Update with Aggregation Pipeline)来实现需求,无需拆分操作,一条查询就能完成数组的合并与更新:
// 假设待更新的新数据存储在变量updatedData中 const updatedData = { "_id": "row1", "spreadSheetId": "sheet1", "data": [ { "id": "field2", "value": "value2 updated" }, { "id": "field3", "value": "value3" } ] }; db.rows.updateOne( { _id: updatedData._id }, [ // 1. 合并原data数组与新传入的data数组 { $set: { mergedData: { $concatArrays: ["$data", updatedData.data] } } }, // 2. 按id分组,保留每个id的最新值(新数据在合并数组后方,$last取最后出现的条目) { $set: { groupedData: { $arrayToObject: { $map: { input: { $group: { _id: "$mergedData.id", value: { $last: "$mergedData.value" } } }, in: { k: "$$this._id", v: { id: "$$this._id", value: "$$this.value" } } } } } } }, // 3. 将分组后的对象转回数组格式,覆盖原data字段 { $set: { data: { $objectToArray: "$groupedData" } } }, // 4. 清理临时字段 { $unset: ["mergedData", "groupedData"] } ] );
逻辑说明:
- $concatArrays:将数据库中原有的
data数组和新传入的data数组合并为临时数组mergedData。 - $group + $arrayToObject:对合并后的数组按
id分组,用$last提取每个id对应的最新值(新数据在合并数组的后续位置,会自动覆盖旧值),再转换为键值对对象。 - $objectToArray:把分组后的键值对对象转回数组格式,替换原有的
data字段。 - $unset:删除过程中生成的临时字段,保持文档结构整洁。
执行后,文档会变为预期格式:
{ "_id": "row1", "spreadSheetId": "sheet1", "data": [ { "id": "field1", "value": "value1" }, { "id": "field2", "value": "value2 updated" }, { "id": "field3", "value": "value3" } ] }
内容的提问来源于stack exchange,提问作者vcmkrtchyan
相关产品推荐
相关产品推荐

