保存 Mongoose Schema 的子级数组,然后将返回的 ID 添加到父级

Saving array of children of a Mongoose Schema and then adding returned IDs to parent

我正在尝试遍历对象数组,将它们保存到 MongoDB,然后将 returned ObjectIds 添加到父架构,然后也将其保存。我在这里不知所措。

一切都已正确保存,但 Recipe(父级)显然在我获得 Tags(子级)的 returned ObjectIds 之前已保存。我觉得我有点经常使用 asyncawait 关键字。

有人可以帮忙吗?代码已简化,但如果需要,我可以 post 更多。

父架构:

const recipe = new mongoose.Schema(
    {
        name: String,
        ingredients: [
            {
                type: mongoose.SchemaTypes.ObjectId,
                ref: "Ingredient",
            },
        ],
    }
);

子架构:

const ingredientSchema = new mongoose.Schema({
    value:  String,
    label: String,
});

有效负载:

{
    name: "Rezept",
    ingredients: [
        {
            label: "zutat",
            value: "Zutat",
        },
        {
            label: "schokolade",
            value: "Schokolade",
        },
    ],
};

我的路由器:

recipesRouter.post("/", async (req, res) => {
    const { body } = req;
    const saveIngredients = async () => {
        let ingredientIDs = [];
        body.ingredients.map(async (ingredient) => {
            const i = new Ingredient({
                value: ingredient.value,
                label: ingredient.label,
            });

            const savedIngredient = await i.save();
            ingredientIDs.push(savedIngredient._id);
        });
        return ingredientIDs;
    };    

    const recipe = new Recipe({
        name: body.name,        
        ingredients: (await saveIngredients()) || [],
       
    });
    const savedRecipe = await recipe.save();
    res.status(201).json(savedRecipe);
});

返回的食谱:

savedRecipe: {
    name: 'asd',
    ingredients: [],
    _id: new ObjectId("62782b45a431e6efb7b8b1a7"),
}

正如我所说,在此之后,单独的成分和配方都会保存到 MongoDB,但不会保存配方中的成分 ID。 returned 配方在 ingredients 中有一个空数组。我想在 MongoDB 可以 return 成分的 ObjectId 之前,食谱保存得太早了。

感谢您的帮助。

首先,您的 post 方法是异步的,因此其中的所有内容都自动包装在已解析的承诺中。

你真的需要让你的 saveIngredients 成为异步的吗?恕我直言,最好不要让 saveIngredients 处于另一个异步状态。

然后我们可以删除空列表,先等待 saveIngredients() 完成。

 const recipe = new Recipe({
        name: body.name,        
        ingredients: await saveIngredients(),      
 });

您的猜测是正确的,因为您提供了 [] 作为默认值,因此无需等待 saveIngredients,因此所有条件都已满足,因此首先保存了 Recipe。你的 saveIngredients 是 运行 并行的。

我明白了。结果 async.map.foreach 中并不顺利。我把它变成了一个简单的for loop。它仍然是 bloated/lot 个步骤,但它有效!

recipesRouter.post("/", async (req, res) => {
    const { body } = req;

    const saveIngredients = async () => {
        let ingredientIDs = [];
        for (let i = 0; i < body.ingredients.length; i++) {
            const el = body.ingredients[i];
            const ing = new Ingredient({
                value: el.value,
                label: el.label,
            });
            const savedIngredient = await ing.save();
            ingredientIDs.push(savedIngredient._id);
        }
        return ingredientIDs;
    };

    const ingredientIDs = await saveIngredients();

    const recipe = new Recipe({
        name: body.name,
        ingredients: ingredientIDs,
    });

    const savedRecipe = await recipe.save();
    res.status(201).json(savedRecipe);
});