[英]How to sum the values from multiple documents in one collection and push total sum to document in another collection
I have recipes and ingredients.我有食谱和配料。 Each has its own model and each has its own controller.每个都有自己的 model,每个都有自己的 controller。 Each recipe has multiple ingredients.每个食谱都有多种成分。 In the recipe model, the ingredients are listed as an array of ingredient ids (in the code below, I call them ingIds in the recipe model).在配方 model 中,成分被列为成分 ID 数组(在下面的代码中,我在配方模型中将它们称为 ingIds)。 Each ingredient can belong to more than one recipe.每种成分可以属于多个配方。 Each ingredient has a calorie amount.每种成分都有卡路里量。 In the ingredient model, I named the field calories.在成分 model 中,我将字段命名为卡路里。 I'm trying to programmatically total the calorie amount for each recipe based on the combined calorie amounts of all the ingredients in the recipe.我正在尝试根据配方中所有成分的总卡路里量以编程方式总计每个配方的卡路里量。 I have the code below that seems to work, kind of.我有下面的代码似乎可以工作,有点。 I get the correct result in Postman when I get all recipes.当我得到所有食谱时,我在 Postman 中得到了正确的结果。 However, I can't get the data in mongodb to update the total calorie count in the recipe document (the calorie-count field I named "score). Any ideas what I'm doing wrong?但是,我无法获取 mongodb 中的数据来更新食谱文档中的总卡路里计数(我命名为“分数”的卡路里计数字段)。知道我做错了什么吗?
I've tried populating the recipe model with the ingredient documents and then summing the nested calorie field, but I can't figure out how to sum the totals of the nested calorie field.我尝试使用成分文档填充配方 model,然后对嵌套卡路里字段求和,但我不知道如何对嵌套卡路里字段的总数求和。 I've also successfully calculated the totals and posted it to the database when creating a new ingredient using embedded url during posting, but that doesn't work because that's good only if the ingredient belongs to only one recipe.在发布期间使用嵌入式 url 创建新成分时,我还成功地计算了总数并将其发布到数据库中,但这不起作用,因为只有当成分仅属于一个配方时才有效。 Here, I have ingredients belonging to multiple recipes.在这里,我有属于多个食谱的成分。
Below are code snippets for how I'm currently approaching this.以下是我目前处理此问题的代码片段。 Recipe model has an array of ingredient Ids.配方 model 具有一系列成分 ID。 The recipe controller looks at the ingredients documents for ones with the matching Id.配方 controller 查看具有匹配 ID 的成分文档。 Then, from the matching ingredients documents, the recipe controller sums the calories fields and saves it to "score".然后,从匹配的成分文档中,配方 controller 对卡路里字段求和并将其保存到“分数”。 When I get all recipes in postman, the output in postman is correct.当我得到 postman 中的所有食谱时,postman 中的 output 是正确的。 It shows the score field with the correct value.它显示具有正确值的分数字段。 However, the mongodb database does not update the score field in the recipe document.但是,mongodb 数据库不会更新配方文档中的分数字段。
// Recipe Controller // 配方 Controller
...
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
}
});
});
...
// Recipe Model // // 配方 Model //
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;
// Ingredient Model // // 成分 Model //
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;
By the way, where are you writing the score value back to MongoDB?顺便问一下,你在哪里将分数值写回 MongoDB? Here you are using aggregation - that means the $addFields - just adds the new fields to the documents from the previous stage of aggregation, so that the next stage in the aggregation finds those fields, that means the output of aggregation contains those fields.在这里您使用聚合 - 这意味着 $addFields - 只是将新字段添加到聚合的前一阶段的文档中,以便聚合的下一阶段找到这些字段,这意味着聚合的 output 包含这些字段。 But it doesn't store that in the DB.但它不会将其存储在数据库中。
If you want to write the results of aggregation back to DB use $out or $merge如果要将聚合结果写回数据库,请使用 $out 或 $merge
See https://docs.mongodb.com/manual/reference/operator/aggregation/out/请参阅https://docs.mongodb.com/manual/reference/operator/aggregation/out/
https://docs.mongodb.com/manual/reference/operator/aggregation/merge/ https://docs.mongodb.com/manual/reference/operator/aggregation/merge/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.