文章的猫鼬模式

Posted

技术标签:

【中文标题】文章的猫鼬模式【英文标题】: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,它可以与文章相关联。 【参考方案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);

);

【讨论】:

以上是关于文章的猫鼬模式的主要内容,如果未能解决你的问题,请参考以下文章

创建包含对象数组的猫鼬模式

带有数组的猫鼬模式

带有数组的猫鼬模式

用于续集模型的猫鼬模式

如何在我的猫鼬模式中引用多个模式?

带有嵌套可选对象的猫鼬模式