Как вставить в гнездо документ с помощью поста мангуста имеет много комментариев, комментарий имеет много ответов - PullRequest
0 голосов
/ 10 октября 2019

Мой 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 к конкретным post и comments этих данных запроса {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 ]

2 голосов
/ 10 октября 2019

Вы можете использовать операцию update и оператор positional $ для выполнения этого варианта использования.

Пример:

app.js add 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 голос
/ 14 октября 2019

Попробуйте:

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, чтобы вы могли протестировать ?

...