MongoDB如何通过ID将数组从draft字段移至publish字段
MongoDB 数组元素迁移:从draft移至publish(仅已知ID)
数据结构说明
Schema定义
{ publish: [[ { type: String, required: true }, { type: String, required: true } ]], draft: [[ { type: String, required: true }, { type: String, required: true } ]] }
数据库示例数据
{ "draft": [ [ "Panic 2", "63d2648d373f7fea3fa9d387_1681628752497" ], // 其他子数组... ], "publish": [ [ "Ruins Exploration Gone Wrong!", "63d2648d373f7fea3fa9d387_1681628787816" ], [ "Fresh Start", "63d2648d373f7fea3fa9d387_1681628805269" ], // 其他子数组... ] }
需求
需要将draft数组中包含ID"63d2648d373f7fea3fa9d387_1681628752497"的子数组(即["Panic 2","63d2648d373f7fea3fa9d387_1681628752497"])移至publish数组,目前仅能实现从draft中移除该子数组,无法完成添加到publish的操作。
解决方案
使用MongoDB的聚合管道更新(需MongoDB 4.2及以上版本支持),通过以下步骤完成迁移:
MongoDB Shell 语句
db.yourCollection.updateOne( // 匹配包含目标ID的文档 { "draft.1": "63d2648d373f7fea3fa9d387_1681628752497" }, [ // 1. 提取draft中要迁移的子数组到临时字段 { $addFields: { targetItem: { $first: { $filter: { input: "$draft", cond: { $eq: ["$$this.1", "63d2648d373f7fea3fa9d387_1681628752497"] } } } } } }, // 2. 更新publish数组,添加目标子数组;同时更新draft数组,移除目标子数组 { $set: { publish: { $concatArrays: ["$publish", ["$targetItem"]] }, draft: { $filter: { input: "$draft", cond: { $ne: ["$$this.1", "63d2648d373f7fea3fa9d387_1681628752497"] } } } } }, // 3. 删除临时字段 { $unset: "targetItem" } ] )
Mongoose 写法(Node.js)
const YourModel = require('./yourModelPath'); YourModel.updateOne( { "draft.1": "63d2648d373f7fea3fa9d387_1681628752497" }, [ { $addFields: { targetItem: { $first: { $filter: { input: "$draft", cond: { $eq: ["$$this.1", "63d2648d373f7fea3fa9d387_1681628752497"] } } } } } }, { $set: { publish: { $concatArrays: ["$publish", ["$targetItem"]] }, draft: { $filter: { input: "$draft", cond: { $ne: ["$$this.1", "63d2648d373f7fea3fa9d387_1681628752497"] } } } } }, { $unset: "targetItem" } ] ).then(result => { console.log('迁移完成:', result); }).catch(err => { console.error('迁移失败:', err); });
逻辑说明
- 匹配条件:通过
"draft.1"定位到draft子数组的第二个元素为目标ID的文档。 - 提取目标子数组:用
$filter筛选出draft中包含目标ID的子数组,存入临时字段targetItem。 - 更新数组:
- 用
$concatArrays将targetItem追加到publish数组末尾。 - 再次用
$filter移除draft中的目标子数组。
- 用
- 清理临时字段:删除
targetItem,避免污染文档结构。
内容的提问来源于stack exchange,提问作者Fallen
相关产品推荐
相关产品推荐

