如何将MongoDB中Tag数据迁移至Group结构?
MongoDB 标签转分组的迁移实现
完整迁移脚本
直接运行以下聚合命令即可完成迁移,它会为每个Tag生成对应Group并关联绑定的电脑和设置:
db.tag.aggregate([ // 关联同分类下绑定当前标签的电脑 { $lookup: { from: "computer", let: { tagId: "$_id", category: "$category" }, pipeline: [ { $match: { $expr: { $and: [ { $eq: ["$category", "$$category"] }, { $in: ["$$tagId", "$tags"] } ] } } }, { $project: { _id: 1 } } ], as: "computers" } }, // 将电脑文档数组转换为纯ID数组 { $addFields: { computers: { $map: { input: "$computers", as: "c", in: "$$c._id" } } } }, // 关联同分类下绑定当前标签的设置 { $lookup: { from: "setting", let: { tagId: "$_id", category: "$category" }, pipeline: [ { $match: { $expr: { $and: [ { $eq: ["$category", "$$category"] }, { $in: ["$$tagId", "$tags"] } ] } } }, { $project: { _id: 1 } } ], as: "settings" } }, // 将设置文档数组转换为纯ID数组 { $addFields: { settings: { $map: { input: "$settings", as: "s", in: "$$s._id" } } } }, // 构造Group文档结构 { $project: { _id: 0, name: "$name", category: "$category", computers: "$computers", settings: "$settings" } }, // 将结果写入groups集合(存在则替换,不存在则插入) { $merge: { into: "groups", on: ["name", "category"], whenMatched: "replace", whenNotMatched: "insert" } } ])
关键阶段说明
- 两次
$lookup关联:分别从computer和setting集合中筛选出同分类且绑定当前标签的文档,仅保留_id字段,避免冗余数据。 $map转换数组格式:把关联得到的文档数组转换成纯_id的数组,匹配groups集合的字段要求。$merge写入目标集合:以name+category作为唯一标识,确保每个标签只生成一个对应分组;若已存在同名同分类的分组,会直接替换(可根据需求修改whenMatched参数,比如改为keepExisting保留原有数据)。
优化建议
- 提前创建索引提升关联效率:
// 给computer集合创建复合索引 db.computer.createIndex({ category: 1, tags: 1 }) // 给setting集合创建复合索引 db.setting.createIndex({ category: 1, tags: 1 }) - 若数据量极大,可通过
$match按category分批处理,避免单次聚合压力过大。
内容的提问来源于stack exchange,提问作者TheStranger
相关产品推荐
相关产品推荐

