Mongoose:保存后填充

我有一个项目,我将 MERN 堆栈与 Redux 一起使用。

当我使用 get 请求获取普通数据时,在干净的页面刷新后一切正常,因为我可以使用 referenced data 填充查询,但是当我保存例如 *new data *,在 response json 中,我只接收 ObjectID 的原始数据,而不是它的引用数据。

我相信我需要使用新查询或类似于 .populate 的内容填充保存的响应,以获取引用的数据,但我不知道这样做。

我已经尝试过我在这里读过的东西,例如 execPopulate 上的 save() ,但没有奏效。

带有 post 请求的响应 JSON 示例:

{
  "suggestion": "61cb83b1e7a2d3469d2adc9e",
  "user": "61b4a9253f40b9c22969d11f",
  "content": "testing content",
  "rating": 3,
  "spoiler": false,
  "_id": "61d7df8c5883e282879c6fb9",
  "date": "2022-01-07T06:37:00.196Z",
  "upvotes": [],
  "__v": 0
}

带有 get 请求的响应示例我也希望在 save 中接收,请注意字段 suggestionuser 已填充:

 {
    "_id": "61d7df8c5883e282879c6fb9",
    "suggestion": {
      "_id": "61cb83b1e7a2d3469d2adc9e",
      "title": "Beyond",
      "suggestion_type": "Book",
      "image": "91b2d138-883a-4fab-8e0c-a554dd466349.png",
      "token": "LSSRuE"
    },
    "user": {
      "_id": "61b4a9253f40b9c22969d11f",
      "username": "test_user",
      "avatar": "https://i.pinimg.com/2349087qsbjkqsbd.jpg"
    },
    "content": "Testing content",
    "rating": 3,
    "spoiler": false,
    "date": "2022-01-07T06:37:00.196Z",
    "__v": 0
  }

保存路线:

router.post(
  '/:token/reviews',
  [auth, [check('rating', 'Rating is required').not().isEmpty()]],
  async (req, res) => {

    try {
      const suggestion = await Suggestion.findOne({ token: req.params.token });

      const review = await Review.find({
        suggestion: suggestion.id,
      });          

      const newReview = new Review({
        content: req.body.content,
        rating: req.body.rating,
        spoiler: req.body.spoiler,
        user: req.user.id,
        suggestion: suggestion.id,
      });

      await newReview.save();

      res.json(newReview);
    } catch (error) {
      console.error(error.message);
      res.status(500).send('Server Error');
    }
  }
);

获取路线:

router.get('/:token/reviews/', auth, async (req, res) => {
  try {
    const suggestion = await Suggestion.findOne({
      token: req.params.token,
    });
    const review = await Review.find({
      suggestion: suggestion.id,
    })
      .populate('user', ['avatar', 'username', 'id'])
      .populate('suggestion', [
        'id',
        'token',
        'title',
        'image',
        'suggestion_type',
      ]);

    if (!review) {
      res
        .status(404)
        .json({ msg: 'No reviews found for the specified suggestion' });
    }

    res.json(review);
  } catch (error) {
    console.error(error.message);
    if (error.kind === 'ObjectId') {
      res.status(404).json({ msg: 'Review not found' });
    }
    res.status(500).send('Server Error');
  }
});

评论模型:

const mongoose = require('mongoose');

const ReviewSchema = new mongoose.Schema({
  suggestion: { type: mongoose.Schema.Types.ObjectId, ref: 'suggestion' },

  user: { type: mongoose.Schema.Types.ObjectId, ref: 'user' },

  date: { type: Date, default: Date.now },

  content: {
    type: String,
  },
  rating: {
    type: Number,
  },
  spoiler: { type: Boolean, default: 0 },

});

module.exports = mongoose.model('review', ReviewSchema);
stack overflow Mongoose : populate after save
原文答案

答案:

作者头像

解决了。

我在 await newReview.populate('user'); 之后添加了这一行 await newReview.save();

来自官方文档: https://mongoosejs.com/docs/populate.html#populate_an_existing_mongoose_document

填充现有文档

如果你有一个现有的 mongoose 文档并且想要填充它的一些路径,你可以使用 Document#populate() 方法。

const person = await Person.findOne({ name: 'Ian Fleming' });

person.populated('stories'); // null

// Call the `populate()` method on a document to populate a path.
await person.populate('stories');

person.populated('stories'); // Array of ObjectIds
person.stories[0].name; // 'Casino Royale'