Как суммировать значения из нескольких документов в одной коллекции и вывести общую сумму на документ в другой коллекции - PullRequest
0 голосов
/ 27 сентября 2019

У меня есть рецепты и ингредиенты.У каждого своя модель и у каждого свой контроллер.Каждый рецепт имеет несколько ингредиентов.В модели рецепта ингредиенты перечислены как массив идентификаторов ингредиентов (в приведенном ниже коде я называю их ingIds в модели рецепта).Каждый ингредиент может принадлежать более чем одному рецепту.Каждый ингредиент имеет количество калорий.В модели ингредиента я назвал поле калорий.Я пытаюсь программно суммировать количество калорий для каждого рецепта на основе объединенных количеств калорий всех ингредиентов в рецепте.У меня есть код ниже, который, кажется, работает, вроде.Я получаю правильный результат в Почтальоне, когда получаю все рецепты.Однако я не могу получить данные в mongodb для обновления общего количества калорий в документе рецепта (поле счетчика калорий, которое я назвал «оценка»). Есть идеи, что я делаю неправильно?

I 'Я пытался заполнить модель рецепта документами с ингредиентами, а затем суммировать вложенное поле калорий, но я не могу понять, как суммировать итоги вложенного поля калорий. Я также успешно рассчитал итоги и разместил его в базе данных.при создании нового ингредиента с использованием встроенного URL во время публикации, но это не работает, потому что это хорошо, только если ингредиент принадлежит только одному рецепту. Здесь у меня есть ингредиенты, относящиеся к нескольким рецептам.

Ниже приведены фрагменты кодао том, как я сейчас подхожу к этому. Модель рецепта имеет массив идентификаторов ингредиентов. Контроллер рецептов просматривает документы ингредиентов для продуктов с соответствующим идентификатором. Затем, из документов соответствующих ингредиентов, контроллер рецептов суммирует поля калорий и сохраняетэто "забить". Когда я получаюБуду в рецептах почтальона, вывод в почтальоне правильный.Показывает поле оценки с правильным значением.Однако база данных 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;

1 Ответ

1 голос
/ 27 сентября 2019

Кстати, где вы записываете значение счета обратно в MongoDB?Здесь вы используете агрегацию - это означает, что $ addFields - просто добавляет новые поля в документы с предыдущего этапа агрегации, так что следующий этап агрегации находит эти поля, что означает, что выходные данные агрегации содержат эти поля.Но он не сохраняет это в БД.

Если вы хотите записать результаты агрегирования обратно в БД, используйте $ out или $ merge

См. https://docs.mongodb.com/manual/reference/operator/aggregation/out/

https://docs.mongodb.com/manual/reference/operator/aggregation/merge/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...