简体   繁体   English

如何对一个集合中多个文档的值求和并将总和推送到另一个集合中的文档

[英]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.

相关问题 如何使用mongoose计算mongodb集合文档中的字段总和 - How to calculate sum of fields from mongodb collection documents using mongoose 如何将具有值的集合中的所有文档以 map firestore web 的形式推送到另一个集合 - How to push all the documents in a collection with values to another collection in form of map firestore web 如何在具有多个条件的 MongoDB 集合中的所有文档中求和键的值 - How to sum the value of a key across all documents in a MongoDB collection with multiple conditions 查看子集合文档以进行更新并返回父集合中值的总和的 Firebase 函数 - Firebase Function that looks into child collection documents for update and returns sum of values in parent collection 从另一个数组中的一个数组中查找元素并将总价格求和 - Find elements from one array in another one and Sum the Total Price 如何使用另一个集合中的字段值更新Mongodb集合中的文档 - How to update document in Mongodb collection with a field value from another collection 按xpages中的总值对文档集合进行排序 - Sort document collection by values total in xpages 如何使用一个集合中的文档字段从不同集合中检索另一个文档字段? - How do I use a document's field from one collection to retrieve another document field from a different collection? math.sum 如何将一组值作为参数传递? - math.sum how to pass a collection of values as argument? 骨干集合:检索集合的不同值并求和这些不同值 - Backbone collection: Retrieve distinct values of a collection and sum the distinct values
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM