【问题标题】:How to push an object in an array in Mongoose (error)如何在 Mongoose 的数组中推送对象(错误)
【发布时间】:2018-05-23 13:14:22
【问题描述】:

我正在使用 Mongoose 和 Mongo 在 Node 服务器中创建一个路由,它将评论存储在 blogPost 的 cmets 数组中(我将发布模型代码)。当我尝试执行查询时,它给了我以下错误: Postman error
这些是我的模型和路线:

blogPost 模型

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const BlogPostSchema = new Schema({
  content: {
    type: String,
    validate: {
      validator: (content) => content.length > 5,
      message: 'Content must contain at least 6 characters.'
    },
    required: [true, 'Content must be filled in.']
  },
  rating: Number,
  title: String,
  user: { type: Schema.Types.ObjectId, ref: 'user' },
  board: {type: Schema.Types.ObjectId, ref: 'board'},
  comments: [{
    type: Schema.Types.ObjectId,
    ref: 'comment'
  }]
});

const BlogPost = mongoose.model('blogPost', BlogPostSchema);

module.exports = BlogPost;

评论模型

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const CommentSchema = new Schema({
  content: {
    type: String,
    validate: {
      validator: (content) => content.length > 5,
      message: 'Content must contain at least 6 characters.'
    },
    required: [true, 'Content must be filled in.']
  },
  user: { type: Schema.Types.ObjectId, ref: 'user' },
  rating: Number

  // board: Board
});

// UserSchema.virtual('postCount').get(function(){
//   return this.posts.length;
// });

const Comment = mongoose.model('comment', CommentSchema);

module.exports = Comment;

路线

routes.put('/blogPosts/:id/comment', function(req, res) {
    const blogPostId = req.param('id');
    const commentProps = req.body;

    BlogPost.findById(req.params.id)
        .then((blogPost) => {
          blogPost.comments.push(commentProps);
          blogPost.save();
        })
    .catch((error) => res.status(400).json(error))
});

非常感谢任何帮助。

【问题讨论】:

标签: node.js database mongodb mongoose nosql


【解决方案1】:

问题是您将整个评论对象推送到一个只应该有 objectids 的数组中。

dnickless answer 使用带有引用的解决方案,这意味着您有一个博客帖子集合和一个 cmets 集合。博文文档将使用 objectids 引用他们的 cmets。

您还可以将 blogpost 模型更改为使用嵌入而不是引用,这意味着 cmets 将作为子文档成为 blogpost 文档的一部分。关于更好的herehere,有几个很好的讨论。简短的回答是,它取决于用例。您可以选择自己想使用的。

嵌入的方法如下:

博文模型:

const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const commentSchema = require('./comment.model');

const BlogPostSchema = new Schema({
  content: {
    type: String,
    validate: {
      validator: (content) => content.length > 5,
      message: 'Content must contain at least 6 characters.'
    },
    required: [true, 'Content must be filled in.']
  },
  rating: Number,
  title: String,
  user: { type: Schema.Types.ObjectId, ref: 'user' },
  board: {type: Schema.Types.ObjectId, ref: 'board'},
  comments: [commentSchema]
});

const BlogPost = mongoose.model('blogPost', BlogPostSchema);

module.exports = BlogPost;

注意 cmets 数组如何使用注释模式而不是对象 ID 数组。评论模型必须稍微改变一下:

评论模型:

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const CommentSchema = new Schema({
  content: {
    type: String,
    validate: {
      validator: (content) => content.length > 5,
      message: 'Content must contain at least 6 characters.'
    },
    required: [true, 'Content must be filled in.']
  },
  user: { type: Schema.Types.ObjectId, ref: 'user' },
  rating: Number

  // board: Board
});

// UserSchema.virtual('postCount').get(function(){
//   return this.posts.length;
// });

module.exports = CommentSchema;

const Comment = mongoose.model('comment', CommentSchema); 已被删除。架构不应再注册,并且 cmets 将没有自己的集合。现在正在导出架构而不是已注册的模型。

添加 cmets 的原始代码应该在那之后工作。评论将成为博文文档的一部分,而不是在他们自己的收藏中。

【讨论】:

  • 如果我通过子文档的方式来做,我还能得到一个用户的 cmets 列表吗?还是 blogPost 现在只能访问 cmets?
  • @Mike 您仍然可以获得用户的 cmets 列表,但这比在单独的集合中拥有 cmets 时要困难一些。规范化模型(引用)更易于使用,非规范化模型(嵌入)如果处理得当,可以提供更高的读取性能,因为它们不必引用其他集合。有更多关于here的信息。
【解决方案2】:

您不想将整个comment 推入comments 数组,而只是将其推入_id。所以像这样的东西(未经测试):

// first save the comment
Comment.create(commentProps, function(err, comment) {
    if(err)
    {
      // save the world
    }
    else
    {
        BlogPost.update({ _id: req.param('id') }, { $push: { comments: comment._id } }, function(err, numberAffected, raw) { /*...*/ });
    });

【讨论】:

    猜你喜欢
    • 2018-06-17
    • 1970-01-01
    • 1970-01-01
    • 2019-04-08
    • 1970-01-01
    • 2020-02-05
    • 2018-09-14
    • 1970-01-01
    • 2020-07-08
    相关资源
    最近更新 更多