Mongoose嵌套模式

时间:2017-05-09 12:30:57

标签: node.js mongodb express mongoose

我正在创建一个用于记录锻炼的应用程序,而我在使用Mongoose时遇到了一些问题。

我有两个模式,一个用于锻炼,另一个用于锻炼。当用户添加新练习时,我希望将其存储在锻炼中,我一直在尝试这种方式。

现在,练习被保存在我的MongoDB中的不同集合中(不知道这是否是最好的方法),我认为它应该将练习保存在workout.exercises中,但是只是objectID。我该如何解决这个问题?看过populate函数,但无法弄清楚如何让它工作。

addExercises

export function addExercise(req, res) {
  if (!req.body.exercise.title) {
    res.status(403).end();
  }

  const newExercise = new Exercise(req.body.exercise);

  // Let's sanitize inputs
  newExercise.title = sanitizeHtml(newExercise.title);
  newExercise.cuid = cuid();
  newExercise.sets = [];

  newExercise.save((err, saved) => {
    if (err) res.status(500).send(err);
  });

  Workout
    .findOneAndUpdate(
      {cuid: req.body.exercise.workoutCUID},
      {$push: {exercises: newExercise}},
      {upsert: true, new: true},
      function (err, data) {
        if (err) console.log(err);
      });
}

getExercises

export function getExercises(req, res) {
  Workout.findOne({cuid: req.params.cuid}).exec((err, workout) => {
    if (err) {
      res.status(500).send(err);
    }
    console.log(workout);
    let exercises = workout.exercises;
    res.json({exercises});
  });
}

锻炼

import mongoose from "mongoose";
const Schema = mongoose.Schema;
var Exercise = require('./exercise');

const workoutSchema = new Schema({
  title:     {type: 'String', required: true},
  cuid:      {type: 'String', required: true},
  slug:      {type: 'String', required: true},
  userID:    {type: 'String', required: true},
  exercises: [{ type: Schema.Types.ObjectId, ref: 'Exercise' }],
  date:      {type: 'Date', default: Date.now, required: true},
});

export default mongoose.model('Workout', workoutSchema);

运动

import mongoose from "mongoose";
const Schema = mongoose.Schema;
var Workout = require('./workout');

const exerciseSchema = new Schema({
  title:       {type: 'String', required: true},
  cuid:        {type: 'String', required: true},
  workoutCUID: {type: 'String', required: true},
  sets:        {type: 'Array', "default": [], required: true}
});

export default mongoose.model('Exercise', exerciseSchema);

2 个答案:

答案 0 :(得分:1)

根据您的Workout架构,您将Exercises字段的类型声明为[{ type: Schema.Types.ObjectId, ref: 'Exercise' }]。这意味着该字段应该是Mongoose ObjectId的数组。

您似乎正在尝试将整个exercise对象添加到锻炼的exercises字段,而不仅仅是ObjectId。尝试以这种方式修改它:

const newExercise = new Exercise(req.body.exercise);

// Let's sanitize inputs
newExercise.title = sanitizeHtml(newExercise.title);
newExercise.cuid = cuid();
newExercise.sets = [];

newExercise.save((err, saved) => {
  if (err) res.status(500).send(err);
  // Nest the Workout update in here to ensure that the new exercise saved correctly before proceeding
  Workout
      .findOneAndUpdate(
        {cuid: req.body.exercise.workoutCUID},
        // push just the _id, not the whole object
        {$push: {exercises: newExercise._id}}, 
        {upsert: true, new: true},
        function (err, data) {
          if (err) console.log(err);
        });

});

现在您已在锻炼字段中正确保存了ObjectId,.populate在查询锻炼时应该有效:

Workout.findById(id).populate("exercises").exec((err, workout) => {
 // handle error and do stuff with the workout
})

答案 1 :(得分:0)

 Workout.findById(req.params.id).populate("exercises").exec((err,workout) =>{
 res.status(200).json(workout);
})

它应该以这种方式工作