自从我们更改架构以来,我编写了“向上”迁移。然而,当我运行该命令时,迁移仅部分应用。例如,应该有 4 个受影响的记录,但只有 1、2 或 3 个被有效更改,有时甚至没有。为了进行调查,我在函数中编写了一些控制台日志,但如上所述,仅打印了一些(或没有),并且没有出现错误。这就是函数(当应用更改时,结果就是我所期望的)。我是 MongoDb 和迁移包的新手,我担心这种不一致的结果 套餐: “迁移”:“^2.1.0”, “猫鼬”:“^8.5.1”,
module.exports.up = async () => {
try {
// Fetch SpecType documents that have instructions array not empty
const specTypes = await SpecType.find({ instructions: { $exists: true, $ne: [] } }).lean();
for (const specType of specTypes) {
console.log('specType', specType);
const newInstructions = [];
await Promise.all(
specType.instructions.map(async instruction => {
let existingInstruction = await Instruction.findOne({ text: instruction });
if (!existingInstruction) {
existingInstruction = await new Instruction({ text: instruction }).save();
}
newInstructions.push({
id: existingInstruction._id,
text: existingInstruction.text
});
return Promise.resolve();
})
);
console.log('NEW', newInstructions);
await SpecType.updateOne({ _id: specType._id }, { $set: { instructions: newInstructions } });
}
console.log('Migration completed successfully.');
} catch (error) {
console.error('An error occurred during migration:', error);
throw error;
}
};
您在
Promise.all
循环内使用 for...of
,这会创建并行异步操作,但您也在其外部更改 newInstructions
数组。这是有问题的,因为数组突变可能与 Promise.all
操作的完成不一致。您可以按顺序处理指令,而不是在 Promise.all
循环内使用 for...of
。
此外,您在获取
.lean()
文档时使用 SpecType
。这使它们成为普通的 JavaScript 对象,因此它们丢失了任何 Mongoose 特定的方法,例如 .save()
。虽然这对于只读操作来说很好,但如果您稍后尝试直接修改文档,则可能会造成混乱。我不会那样做
module.exports.up = async () => {
try {
// Fetch SpecType documents that have a non-empty instructions array
const specTypes = await SpecType.find({ instructions: { $exists: true, $ne: [] } }).lean();
for (const specType of specTypes) {
console.log('Processing SpecType:', specType._id);
const newInstructions = [];
for (const instruction of specType.instructions) {
let existingInstruction = await Instruction.findOne({ text: instruction });
if (!existingInstruction) {
existingInstruction = await new Instruction({ text: instruction }).save();
}
// Add the instruction to the new array
newInstructions.push({
id: existingInstruction._id,
text: existingInstruction.text,
});
}
// Log the updated instructions array
console.log('Updated instructions for SpecType:', specType._id, newInstructions);
// Update the SpecType document
await SpecType.updateOne({ _id: specType._id }, { $set: { instructions: newInstructions } });
}
console.log('Migration completed successfully.');
} catch (error) {
console.error('An error occurred during migration:', error);
throw error;
}
};