【问题标题】:Mongoose schema for article文章的猫鼬模式
【发布时间】:2020-02-14 15:01:31
【问题描述】:

我正在建立一个新闻网站,我是这个猫鼬模式:

let mongoose = require('mongoose');

let articleSchema = mongoose.Schema({
  image1:{
    type: String,
    required: true
  },
  title:{
    type: String,
    required: true
  },
  author:{
    type: String,
    required: true
  },
  date:{
    type: String,
    required: true
  },
  updated:{
    type: String,
    default: 'not updated'
  },
  title_nd:{
    type: String,
    required: false
  },
  body:{
    type: String,
    required: true
  },
  comments: [commentsSchema],
  likes:{ type:Number, default:0 }
});

let Article = module.exports = mongoose.model('Article', articleSchema);

我想添加一个表单,以便用户可以添加他们的 cmets。 问题是如何为 cmets 创建新架构并将其链接到文章架构,然后如果用户添加评论,则该评论添加到数据库中,然后显示在文章评论部分?

【问题讨论】:

  • 到目前为止,您的commentsSchema 有哪些内容?您可以像创建文章模式一样创建 cmets 模式,只是具有不同的属性和明显不同的模型名称。在您的 cmets 架构中,您可以向您的 cmets 架构添加一个属性,指定一个 ObjectId,它可以与文章相关联。

标签: node.js mongodb mongoose pug mongoose-schema


【解决方案1】:

在我看来,为评论建模一个单独的模式并不是一个好主意,因为它是 one to few mapping 的经典案例,它是嵌入文档的理想用例。为了让您对数据建模有一个基本的了解,我在这里引用了

你需要考虑两个因素:

  • One-to-N 中“N”侧的实体是否需要独立存在?
  • 关系的基数是什么:是一对多吗?一对多;还是一对一?

基于这些因素,您可以选择三种基本的一对 N 架构设计之一:

  • 如果基数是一对多并且不需要在父对象的上下文之外访问嵌入的对象,则嵌入 N 端
  • 如果基数是一对多或者 N 端对象出于任何原因应该独立存在,则使用对 N 端对象的引用数组
  • 如果基数是一对 squillions,则在 N 侧对象中使用对 One-side 的引用

请参考来自 mongodb 博客的一篇写得很好的文章6 Rules of Thumb for MongoDB Schema Design: Part 1

即使在此之后,如果您认为链接到另一个架构是个好主意,请参考这个 SO 问题 - Referencing another schema in Mongoose

【讨论】:

    【解决方案2】:

    所以我找到了解决方案:

    // :id is all articles with all ids
    router.post('/:id', function (req, res) {
      let comment = {};
      comment.body = req.body.body;
      comment.user = req.user;
      comment.date = new Date(Date.now()).toDateString();
    
      // Express validator
      req.checkBody('body').len(5, 100);
    
      let errors = [];
      errors = req.validationErrors();
    
      if(errors) {
        Article.findById(req.params.id, function (err, article) {
          if(err)throw err;
          req.flash('danger', 'Body minimum length is 5 and maximum 100!');
          res.redirect('/articles/'+article.id);
        });
      } else {
        Article.findById(req.params.id, function (err, article) {
          if(err)throw err;
         article.comments.push({'body':comment.body,'user':comment.user,'date':comment.date});
          article.save(function (err) {
            if (err) {
              throw err;
            }else {
              req.flash('success', 'Comment added!');
              res.redirect('/articles/'+article.id);
            }
          });
        });
      }
    });
    

    编辑:上面的代码更易读:

    router.post('/:id', async (req, res) => {
      let article = await Article.findById(req.params.id);
    
      if (!article) res.status("403");
    
      let articleUrl = "/articles/${article.id}";
    
      let comment = {
        body: req.body.body,
        user: req.user,
        date: new Date(Date.now()).toDateString();
      };
    
      if (commment.body.lengh >= 100 || comment.body.length <= 5) {
        req.flash('danger', 'Body minimum length is 5 and maximum 100!');
        return res.redirect(articleUrl);
      }
    
      articles.comments.push(comment);
    
      await article.save();
    
      req.flash('success', 'Comment added!');
      res.redirect(articleUrl);
    
    });
    

    【讨论】:

      猜你喜欢
      • 2016-08-05
      • 2012-02-02
      • 2020-09-18
      • 2015-01-23
      • 1970-01-01
      • 2013-02-23
      • 2018-04-17
      • 2021-09-21
      • 2015-05-20
      相关资源
      最近更新 更多