如何使用猫鼬帖子插入嵌套文档有很多评论,评论有很多回复

时间:2019-10-10 07:47:19

标签: node.js express mongoose

我的posts文档具有以下结构:

{
    "_id" : ObjectId("5d9df11b0e0a6e032bf3117f"),
    "body" : "Sample content post.",
    "date" : ISODate("2019-10-07T11:02:40.126Z"),
    "comments" : [            
        {
            "comment" : "comment on post",
            "_id" : ObjectId("5d9df46e0e0a6e032bf31182"),
            "replies" : [
                { 
                    "reply" : "reply to comment ",
                    "_id" : ObjectId("5d9bec26301798056bb07ab5")
                },
                      ]
        }, 
    ],

}

我想向此请求数据reply的特定postcomments添加新的{data: req.body}

{
  "data": {
    "id_post": "5d9df11b0e0a6e032bf3117f",
    "id_comment": "5d9df46e0e0a6e032bf31182",
    "new_reply": "Another new reply to comment"
  }
}

我正在使用nodejs / express / mongoose,您能否帮助指导我如何添加新回复。

   router.post("/saveReply", function(req, res, next){
     const query = Post.findById(req.body.id_post);
     const updatePost = async () => {
      try {
          await Post.updateOne(
              {
                  "_id": req.body.id_post,
                  "comments._id": req.body.id_comment
              },
              {
                  "$push": {
                      "comments.$.replies": {
                          "reply": req.body.reply,
                      }
                  }
              },
          );
      }
      catch (error) {
          console.log('?', error);
      }
  };

  updatePost().then(() => console.log('✅Post updated successfully!'));

});

2 个答案:

答案 0 :(得分:2)

您可以使用update操作和positional $运算符来完成此用例。

示例:

app.js 添加mongoose连接

const mongoose = require('mongoose');

const dbURI = 'mongodb://localhost:27017/post'

mongoose.Promise = global.Promise;

mongoose.connection.openUri(config.dbURI);

mongoose.connection.on('connecting', () => {
    console.log('connecting to MongoDB...');
});

mongoose.connection.on('connected', () => {
    console.log('Mongoose default connection open to ' + config.dbURI);
});

mongoose.connection.on('error', (err) => {
    console.log('Mongoose default connection error: ' + err);
});

mongoose.connection.on('disconnected', () => {
    console.log('Mongoose default connection disconnected');
    mongoose.connect(dbURI, {server: {auto_reconnect: true}});
});

post.js 模型文件

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

let postSchema = new Schema({
        body: String,
        date:Date,
        comments : Array
    }
);


let postCollection = mongoose.model('posts', postSchema);

module.exports = postCollection;

API

let post = require('post-model-file');


let addReply = async ()=>{

  try{
       await post.update(
             {
               "_id" : ObjectId("5d9df11b0e0a6e032bf3117f"),
               "comments._id" :ObjectId("5d9df46e0e0a6e032bf31182") 
             },
            {
            "$addToSet" : { 
                "comments.$.replies" : {
                            "reply" : "reply to comment ",
                            "_id" : ObjectId("5d9bec26301798056bb07ac5")
                               }
                          }
            }
    );
}
catch(e){

console.error(e)
}
}

有关更多信息,请检查https://docs.mongodb.com/manual/reference/operator/update/positional/

答案 1 :(得分:1)

尝试:

const PostSchema = new Schema({
    body: { type: String, required: true },
    date: { type: String, required: true },
    comments: { type: Array, required: true }
});

/**
Interfaces
**/

interface IPost {
    body: string,
    date: Date,
    comments: IComment[]
}

interface IReply {
    reply: string
}

interface IComment {
    comment: string
    replies: IReply[]
}

interface IPostDocument extends Document, IPost {
    body: string,
    date: Date,
    comments: IComment[]
}

/**
Test ID's
**/
const postID = ObjectId("5d9df11b0e0a6e032bf3117f");
const commentID = ObjectId("5d9df46e0e0a6e032bf31182");
const replyID = ObjectId("5d9bec26301798056bb07ab5");

/**
New post
**/

const post: any = {
    _id: postID,
    body: "New post.",
    date: new Date(),
    comments: [{
        _id: commentID,
        comment: "New comment",
        replies: [
            {
                _id: replyID,
                reply: "New reply"
            }
        ]
    }]
}

/**
Model
**/

const PostModel = model('Post', PostSchema);

/**
Document
**/

const DemoPost = new PostModel(post);

// Demo

const query = PostModel.findById(postID);

query
.then((post) => {
    if (!post) {
        PostModel.create(DemoPost)
            .then(() => {
                console.log('✅New post created! Run the server again to update the post ?');
                process.exit(0);
            })
            .catch(error => console.log('?', error))
    } else {
        const updatePost = async () => {
            try {
                await PostModel.updateOne(
                    {
                        "_id": postID,
                        "comments._id": commentID
                    },
                    {
                        "$push": {
                            "comments.$.replies": {
                                "reply": "Another new reply",
                            }
                        }
                    },

                );
            }
            catch (error) {
                console.log('?', error);
            }
        };

        updatePost().then(() => console.log('✅Post updated successfully!'));
    }
})
.catch(error => console.log('?', error));

注意:如果您使用$addToSet,则回复数组将不接受重复项,您可以使用$push

来解决此问题。

我希望这会有所帮助,如果您有任何问题,我会很乐意将代码推送到GitHub供您测试?