我有食谱和原料。每个都有自己的模型,每个都有自己的控制器。每个食谱都有多种成分。在食谱模型中,食材以食材ID的数组形式列出(在下面的代码中,我在食谱模型中将其称为ingIds)。每种成分可以属于多个食谱。每种成分都有热量。在成分模型中,我命名了字段卡路里。我正在尝试以配方中所有成分的总卡路里含量为基础,以编程方式总计每个配方的卡路里含量。我下面的代码似乎可以工作。当我得到所有食谱时,我在Postman中得到正确的结果。但是,我无法在mongodb中获取数据以更新配方文档中的总卡路里计数(我将卡路里计数字段命名为“分数”。任何想法我做错了吗?
我曾尝试用配料文档填充配方模型,然后对嵌套卡路里字段求和,但是我不知道如何对嵌套卡路里字段的总数求和。在发布过程中使用嵌入的url创建新成分时,我也已经成功计算了总计并将其发布到数据库中,但是这行不通,因为仅当成分仅属于一个配方时这才是好的。在这里,我有属于多个食谱的食材。
下面是我目前正在使用的代码片段。配方模型具有一系列成分ID。配方控制器在配料文档中查找具有匹配ID的配料。然后,配方控制器从匹配的配料文档中对卡路里字段求和,并将其保存为“得分”。当我在邮递员中获取所有食谱时,邮递员中的输出正确。它显示具有正确值的分数字段。但是,mongodb数据库不会更新配方文档中的得分字段。
//配方控制器
...
exports.getPostTotals = catchAsync(async (req, res, next) => {
const stats = await Post.aggregate([
{
$lookup: {
from: "ingredients", // name of the foreign collection
localField: "ingIds",
foreignField: "_id",
as: "lookup-data"
}
},
{
$addFields: {
score: {
$sum: "$lookup-data.calories"
}
}
},
{ $project: { "lookup-data": 0 } }
]);
res.status(200).json({
status: "success",
data: {
stats
}
});
});
...
//食谱模型//
const mongoose = require("mongoose");
const slugify = require("slugify");
const postSchema = new mongoose.Schema(
{
...
ingIds: [{ type: mongoose.Schema.ObjectId, ref: "Ingredient" }],
score: Number,
...
},
{
toJSON: { virtuals: true },
toObject: { virtuals: true }
}
);
...
const Post = mongoose.model("Post", postSchema);
module.exports = Post;
//成分模型//
const mongoose = require("mongoose");
const Post = require("./postModel");
const ingredientSchema = new mongoose.Schema(
{
...
calories: {
type: Number,
required: [true, "An ingredient must have a calorie count."]
...
},
{
toJSON: { virtuals: true },
toObject: { virtuals: true }
}
);
const Ingredient = mongoose.model("Ingredient", ingredientSchema);
module.exports = Ingredient;
顺便说一下,您将分数值写回到MongoDB上吗?在这里,您正在使用聚合-意味着$ addFields-只是将新字段添加到聚合上一阶段中的文档中,以便聚合的下一阶段找到这些字段,这意味着聚合的输出中包含这些字段。但它不会将其存储在数据库中。
如果要将聚合结果写回数据库,请使用$ out或$ merge
请参见https://docs.mongodb.com/manual/reference/operator/aggregation/out/
https://docs.mongodb.com/manual/reference/operator/aggregation/merge/