Node JS mongoose 创建博文评论系统

Posted

技术标签:

【中文标题】Node JS mongoose 创建博文评论系统【英文标题】:Node JS mongoose create a blog post commenting system 【发布时间】:2021-05-02 00:30:25 【问题描述】:

我正在尝试使用 mongoose 和 express 构建一个带有评论系统的简单博客。在这里创建和发布博客没有任何问题,并且每个帖子都可以正确显示。但是,有一些与 cmets 和每个博客相关的问题。 cmets 和 blog post 之间的关系是通过在 post Schema 中应用 mongoose.Schema.Types.ObjectId 建立的,并且创建了 cmets 来存储 cmets id 的数组。我认为架构结构是正确的,我的路由代码中可能存在一些问题,请帮助,谢谢。

    // Post Schema
    const mongoose = require('mongoose');

    const postSchema = new mongoose.Schema(
      title: 
       type: String,
       trim: true,
       required: true
     ,
       text: 
       type: String,
       trim: true,
       required: true
     ,
      date: 
       type: Date,
       default: Date.now
     ,
      comments: [
       type: mongoose.Schema.Types.ObjectId,
       ref: 'Comment'
      ]
    )

    postSchema.virtual('url').get(function()
      return '/post/' + this._id
     )

    module.exports = mongoose.model('Post', postSchema); 


     // Comment Schema 
     
     const mongoose = require('mongoose');

     const commentSchema = new mongoose.Schema(
        text: 
         type: String,
         trim: true,
         required: true
        ,
        date: 
         type: Date,
         default: Date.now
         
        )

      module.exports = mongoose.model('Comment', commentSchema); 

      // Router 

       const express = require('express');
       const Post = require('../models/post');
       const Comment = require('../models/comment');

       const router = new express.Router();


       // Get comments
       router.get('/post/:id/comment', (req, res) => 
           res.render('post-comment', title: 'Post a comment')
       )


       // Create and Post comments, this is where I think I made mistakes

       router.post('/post/:id/comment', async (req, res) => 
           const comment = new Comment(text: req.body.text);
           const post = await Post.findById(req.params.id);
           const savedPost = post.comments.push(comment);

           savedPost.save(function(err, results)
              if(err) console.log(err)
              res.render('post_details', title: 'Post details', comments: 
               results.comments)
             )
          )


        //  Get each post details. 
        // Trying to display comments, but it is all empty and I realized 
        // the comments array is empty, I can see the comments create in 
        // mongodb database why is that?????

       router.get('/post/:id', (req, res) => 
         Post.findById(req.params.id)
             .populate('comments')
             .exec(function(err, results) 
           if(err) console.log(err)
             res.render('post_details', title: 'Post details', post: 
          results, comments: results.comments)
           )
         )

       router.get('/new', (req, res) => 
         res.render('create-post', title: 'Create a post')
        )

       router.post('/new', (req, res) => 
         const post = new Post(
          title: req.body.title,
          text: req.body.text
          );
          post.save(function(err) 
           if(err) console.log(err)
             res.redirect('/')
          )
         )

       router.get('/', (req, res) => 
          Post.find()
             .exec(function(err, results) 
              if(err) console.log(err)

              res.render('posts', title: 'All Posts', posts: results)
           )
       );

      module.exports = router;
      

【问题讨论】:

【参考方案1】:

我发布这个问题已经过去几天了,到目前为止我还没有收到任何答复。但是我已经弄清楚了为什么我的代码不起作用,这篇文章将尝试回答我几天前提出的这个问题,并希望它可以帮助一些遇到同样问题的人。

我这里的问题是创建的每条评论都无法推送到post中的cmets数组中,所以无法显示cmets,因为数组为空。

如果您查看我的 Schema 代码,您可能会意识到我犯了评论模式的错误,因为我没有定义帖子键值对,因此正确的评论和帖子模式应该如下所示。这里的逻辑是每篇博文下面可以有多个cmets,所以post Scheme中的cmets应该创建为一个数组,但是每条评论只能在一篇博文下面,因此评论模式中的post键值对应该是仅在一个对象中

        const mongoose = require('mongoose');

        const commentSchema = new mongoose.Schema(
         text: 
              type: String,
              trim: true,
              required: true
           ,
        date: 
              type: Date,
              default: Date.now
           ,
       // each comment can only relates to one blog, so it's not in array
        post: 
              type: mongoose.Schema.Types.ObjectId,
              ref: 'Post'
           
         )

        module.exports = mongoose.model('Comment', commentSchema);

帖子架构应如下所示

        const mongoose = require('mongoose');

        const postSchema = new mongoose.Schema(
           title: 
             type: String,
             trim: true,
              required: true
           ,
           text: 
             type: String,
             trim: true,
             required: true
           ,
           date: 
             type: Date,
             default: Date.now
            ,
         // a blog post can have multiple comments, so it should be in a array.
         // all comments info should be kept in this array of this blog post.
          comments: [
             type: mongoose.Schema.Types.ObjectId,
             ref: 'Comment'
           ]
           )

           postSchema.virtual('url').get(function()
              return '/post/' + this._id
           )

         module.exports = mongoose.model('Post', postSchema);

我没有做的另一件重要的事情是,每次发布评论时,都应该将这条评论推送到 post.cmets 数组中。我没有做这一步,这就是为什么我的数组总是空的并且没有评论显示。纠正这个问题的代码是文件commentRouter.js(我已经创建了postRouter.js和commentRouter.js),在下面添加代码

         router.post('/post/:id/comment', async (req, res) => 
              // find out which post you are commenting
               const id = req.params.id;
              // get the comment text and record post id
               const comment = new Comment(
               text: req.body.comment,
               post: id
            )
              // save comment
           await comment.save();
              // get this particular post
           const postRelated = await Post.findById(id);
              // push the comment into the post.comments array
           postRelated.comments.push(comment);
              // save and redirect...
           await postRelated.save(function(err) 
           if(err) console.log(err)
           res.redirect('/')
           )

          )

以上是我修复错误的方法,希望它可以帮助某人。

感谢您的阅读

【讨论】:

感谢您的详细解释。我目前有同样的问题。我仍在尝试在数据库中创建新评论,但我不能。您的评论路线路径与我的相同:“posts/:id/comment”。请问,你是如何为你的 app.use() 设置路径的?是app.use(/api/posts/id/comment) array.push 超级简单。谢谢大佬

以上是关于Node JS mongoose 创建博文评论系统的主要内容,如果未能解决你的问题,请参考以下文章

不能使用 Node js(express) 和 MongoDB(mongoose) 对用户配置文件进行审核

使用 Mongoose 更新评论系统平均评分的正确方法

使用 Mongoose 更新评论系统平均评分的正确方法

Node.js/Mongoose 上的“版本错误:未找到匹配的文档”错误

Node.js / Mongoose上的“VersionError:找不到匹配的文档”错误

mongoose .create 给 node.js “ValidationError:验证失败:转换为 [undefined] 值失败......”