在 MongoDb 中运行迁移时结果不一致

问题描述 投票:0回答:1

自从我们更改架构以来,我编写了“向上”迁移。然而,当我运行该命令时,迁移仅部分应用。例如,应该有 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;
  }
};
mongodb migration
1个回答
0
投票

您在

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;
  }
};
© www.soinside.com 2019 - 2024. All rights reserved.