チャールズ
チャールズ

Reputation: 123

Display all comments for each post with ExpressJs and Mongoose

So I've been making an "instagram-like" webapp. Users can make a post (picture+description) and other users can comment on the picture.

Each post contain an array of comment ids. Each comment contain a reference to it's post.

What I can't figure out is how to query (Find all post, for each post get comments -> render view).

Here is what the Schemas look like

//## models/post.js
var Post = new Schema({
  author     : {type: String, required: true},
  desc       : {type: String},
  imageUrl   : {type: String},
  commentsIds: [{type:Schema.ObjectId, ref:'Comment'}],
  likes      : {type: Number, default: 0},
  created_at : {type:Date, default: Date.now}
});

//## models/comment.js
var Comment = new Schema({
  username  : {type: String, required: true},
  content   : {type: String, required: true},
  post      : {type:Schema.ObjectId, ref:'Post'},
  created_at: Date 
});

and my router is like this at the moment "works" as in there's no error, but it is outputting all comments under all posts..not just their respective post like I want.

// routes.js
router.get('/', function(req, res) {
  Post.find(function(err, posts, count){
    Comment.find({post: {$in: posts}}, function ( err, comments, count ){
      res.render( 'index', {
        user: req.user,
        page : 'index',
        title : 'トップページ',
        posts : posts,
        comments : comments
      });
    });
  });
});

Ive read that mongoose work with something called populate, but isnt this just inserting all comments inside the post's? I dont want the post document to become data intensive...

A bit lost.. any help is welcomed, thank you.

Upvotes: 1

Views: 2670

Answers (1)

Patrick Borrelli
Patrick Borrelli

Reputation: 56

Based on your schema, you are already including every comment inside the post the refer to...best not to include an unlimited array in a schema as a matter of good practice, especially since you already have a reference in Comment to the parent post.

However since you already have an array of comments in your Post schema, you can simply do the following to include the full details of each comment in the data returned from your query:

  router.get('/', function(req, res) {
  Post.find({})
    .populate('commentsIds')
    .exec(function(err, posts, count){  
      res.render( 'index', {
        user: req.user,
        page : 'index',
        title : '??????',
        posts : posts
      });
  });
});

Populate doesn't store anything additional in the mongodb you don't already have stored, you are currently storing an array of commentIds in each post, populate simply takes all those comments and substitutes them into the array of commentIds for display of your results.

Upvotes: 2

Related Questions