问题
I'm building an API for my chat application and I wrote the endpoint below to save new messages in MongoDB.
The messages themselves are an array.
Testing this endpoint with Postman returns the newly created message in the response but the message is not added to my array of messages.
router.post('/:id/messages', async (request, response) => {
const chatMessage = new Message({
type: request.body.type,
body: request.body.body,
author: request.body.author
});
try {
const newMessage = await chatMessage.save({ $push: { chatMessage } });
response.status(201).json(newMessage);
} catch (error) {
response.status(400).json({ message: error.message });
}
});
Here's my Mongoose schema for messages:
const mongoose = require('mongoose');
const messageSchema = new mongoose.Schema({
type: {
type: String
},
body: {
type: String
},
author: {
type: String
},
date: {
type: Date,
default: Date.now
}
});
module.exports = mongoose.model('Message', messageSchema);
Any hints on what I've done wrong? Thank you so much! :-)
EDIT_ Mongo DB Sample
回答1:
Please make these changes :
chat schema file :
/** messages schema w.r.t. messages field in chat document */
const messageSchema = new mongoose.Schema({
type: {
type: String
},
body: {
type: String
},
author: {
type: String
},
date: {
type: Date,
default: Date.now
}
});
/** Actual chat schema */
const chatsSchema = new mongoose.Schema({
id: Number,
user1: String,
user2: String,
messages: [messageSchema]
});
function getChatsModel() {
if (mongoose.models && mongoose.models.chats) {
return mongoose.models.chats;
}
return mongoose.model('chats', chatsSchema, 'chats');
}
module.exports = getChatsModel();
Code :
/** Import chats model file here & also do require mongoose */
router.post('/:id/messages', async (request, response) => {
const chatMessage = {
messages: {
type: request.body.type,
body: request.body.body,
author: request.body.author
}
};
try {
const id = mongoose.Types.ObjectId(request.params.id);
const dbResp = await Chats.findOneAndUpdate({ "_id": id }, { $push: chatMessage }, { new: true }).lean(true);
if (dbResp) {
// dbResp will be entire updated document, we're just returning newly added message which is input.
response.status(201).json(chatMessage);
} else {
response.status(400).json({ message: 'Not able to update messages' });
}
} catch (error) {
response.status(500).json({ message: error.message });
}
});
回答2:
According to mongodb documentation .save()
is deprecated: https://docs.mongodb.com/manual/reference/method/db.collection.save/
You should try .update()
command instead as shown in the $push
example documentation:
https://docs.mongodb.com/manual/reference/operator/update/push/
回答3:
There's something with your schema and action that doesn't match.
You're using $push
which is used to append data to an array. Your schema doesn't contain any array.
If your collection contains the messages as documents then you should use .insertOne
instead.
router.post('/:id/messages', async (request, response) => {
const chatMessage = {
type: request.body.type,
body: request.body.body,
author: request.body.author
}
try {
const newMessage = await chatMessage.insertOne(chatMessage);
response.status(201).json(newMessage);
} catch (error) {
response.status(400).json({ message: error.message });
}
})
newMessage
would then contain the created document. Be aware that this code is untested.
来源:https://stackoverflow.com/questions/59438747/cant-add-object-to-mongodb-array-inside-a-document