how can i get data from an db object which is store id of another db in mongoDB

Viewed 224

hi there I am not getting data from a DB object which is storing the id of another DBS, actually, this is a blog website so I am posting comments and acting comments but there are problems I am getting the same comments on all posts but I want, every post should have their own comment. here is post schema

const blogSchema = new mongoose.Schema({
        title: String ,
        content: String,
        image:{data: Buffer,contentType: String},
        comment:[
            {
                type:mongoose.Schema.Types.ObjectId, ref:'Comment'
            }
        ]

    });

here is the comment schema

var commentSchema = new mongoose.Schema({
    name:{
        type:String,
        required: "this field is required"
    },
    comment:{
        type:String,
        required:"this filed is required"
    },
    blog:{
        type:mongoose.Schema.Types.ObjectId,
        ref: 'Blog'
    }

},{
    timestamps: true
    
})

node js router which is getting post but not comment

pp.get("/post/:postname",(req,res)=>{

// const requesttitle = _.lowerCase(req.params.postname);

const requesttitle = req.params.postname;

Blog.findOne({_id: requesttitle}  ,(err ,got)=>{
    if(err){
        console.log(err)
    }else{

      const data= got.comment.find({})
      console.log(data)
        res.render('post',{post:got });
        
    }
})
    

})

1 Answers

I believe the problem lays in your Schema. In your blogSchema you have references to many Comment documents, and in your commentSchema you have a reference to a single "Blog" ( I suggest not naming it "blog" but "post" since that is what it is ) . This duplicative referencation is not necessary in most cases.

Since in your setup a single comment can only be a child of one specific post, this would be the reference I would go for. The post document itself doesn't really need to know directly what comments are included since that information is already hold in the Comment document.

For your post I would suggest the following schema :

// Post Schema
const postSchema = new mongoose.Schema({
  title: String ,
  content: String,
  image: { data: Buffer, contentType: String }
});

For your comment I would suggest the following schema :

// Comment Schema
const commentSchema = new mongoose.Schema({
  name: {
    type: String,
    required: "this field is required"
  },
  comment: {
    type: String,
    required: "this filed is required"
  },
  post: {
    type: mongoose.Schema.Types.ObjectId,
    ref: 'Post'
  }
});

Now sure the next step depends on your whole frontend part is setup up, but having schemas like this would let you do something along the lines of :

pp.get("/post/:id", async (req,res) => {

  const id = req.params.id;

  const post = await Post.findOne({ _id: id });
  const comments = await Comment.find({ post: id });

  res.render('post', {
    post: post,
    comments: comments
  });
        
});

Pros

  • one-directional relation means less work if a comment is created or deleted.
  • possibility to just get comment and/or post or both in one api call.

Cons

  • Requires 2 database calls if post and comments both are requested.

Alternative: Subdocuments

As an alternative to using referenced Documents you can use Subdocuments.

For your commentSchema that means you won't need to create a seperate Model out of it. However your postSchema would need to look like this:

const commentSchema = new mongoose.Schema({
  message : { type : String }
});

const postSchema = new mongoose.Schema({
  comments : [commentSchema]
});

This would by default include all comments of the post if you retrieve the post from the database. However it would also require a different code for interacting with those comments (adding, deleting, ...) but you can read about it in the docs I am sure.

Related