简体   繁体   中英

How would I populate the mongoDB post schema with all comments for post?

I have build two schemas, one for posts and one for comments.

const PostSchema = new Schema(
  {
    title: { type: String, required: true },
    text: { type: String, required: true },
    author: { type: Schema.Types.ObjectId, ref: 'User', required: true },
    status: { type: Boolean, default: true },
  },
  { timestamps: true }
);

, and:

const CommentSchema = new Schema(
  {
    text: { type: String, required: true, minlength: 5 },
    author: { type: String, required: true },
    post: { type: Schema.Types.ObjectId, ref: 'Post' },
  },
  {
    timestamps: true,
  }
);

Now I want to make a GET request which finds all posts and would populate each post with its comments. So far I have this, but I am hitting a wall. If I try to do it like this, I can't add .toArray() , and it doesn't even add new field to the allPosts.

exports.allPosts_GET = (req, res) => {
  Post.find()
    .populate('author')
    .sort('-createdAt')
    .exec((err, allPosts) => {
      if (err) {
        return res.status(500).json({ success: false, msg: err.message });
      } else if (allPosts.length === 0) {
        return res.status(404).json({
          success: false,
          msg: 'No posts find in the database!',
        });
      }
      
      allPosts.map((post) => {
        post.comments = Comment.find({post: post._id}). 
        //to array somehow and populate all posts
        
      });

      console.log(allPostsStore);

      res.status(200).json({ success: true, posts: allPosts });
    });
};

So I came up with a solution, I updated my Post schema that contains an array with reference to ids of comments. Like that:

const PostSchema = new Schema(
  {
    title: { type: String, required: true },
    text: { type: String, required: true },
    author: { type: Schema.Types.ObjectId, ref: 'User', required: true },
    comments: [{ type: Schema.Types.ObjectId, ref: 'Comment' }],
    status: { type: Boolean, default: true },
  },
  { timestamps: true }
);

And then when you make a new comment, you reference it to a post, and also save it to array of comments, like that:

exports.createNewComment_POST = (req, res) => {
  const { text, author, postID } = req.body;

  const newComment = new Comment({
    text,
    author,
    post: postID,
  });

  newComment
    .save()
    .then((comment) => {
      Post.findByIdAndUpdate(
        postID,
        { $push: { comments: comment._id } },
        { new: true, useFindAndModify: false },
        (err, post) => {
          if (err) {
            return res.status(500).json({ success: false, msg: err.message });
          }
          res.status(200).json({ success: true, comment });
        }
      );
    })
    .catch((err) => {
      res.status(500).json({ success: false, msg: err.message });
    });
};

Getting all posts with their comments, you just use find() and populate() , like that:

exports.allPosts_GET = (req, res) => {
  Post.find()
    .populate('author', '-password')
    .populate('comments')
    .sort('-createdAt')
    .exec((err, posts) => {
      if (err) {
        return res.status(500).json({ success: false, msg: err.message });
      } else if (posts.length === 0) {
        return res.status(404).json({
          success: false,
          msg: 'No posts find in the database!',
        });
      }
      res.status(200).json({ success: true, posts: posts });
    });
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM