【发布时间】:2020-10-01 19:14:35
【问题描述】:
我有一个基本的 ChatRoom 和 ChatMessage 架构。对于某种优化,ChatRoom 包含 lastMessage 属性作为 ChatMessage 类型的子文档。
export const ChatMessageSchema = new Schema({
message: {
type: String,
required: true,
},
chatRoomId: {
type: Schema.Types.ObjectId,
required: true,
},
createdBy: {
type: Schema.Types.ObjectId,
required: true,
},
...
}, {
timestamps: true,
});
export const ChatRoomSchema = new Schema({
membersIds: {
type: [Schema.Types.ObjectId],
required: true,
},
lastMessage: {
type: ChatMessageSchema,
},
...
}, {
timestamps: true,
});
因此,每当创建新消息时,我都会尝试将 lastMessage 属性更新/替换为 findOneAndUpdate,就像这样。
const onChatMessagePosted = async ({ chatMessage, chatRoom }) => {
// 1. Doesn't work, throw an "Path `chatRoomId` is required" error
await ChatRoom.findOneAndUpdate(
{ _id: chatRoom._id },
{ $set: { lastMessage: chatMessage } },
{ new: true, runValidators: true },
);
// 2. It works
chatRoom.set({ lastMessage: chatMessage });
await chatRoom.save();
// 3. It works too
await ChatRoom.findOneAndUpdate(
{ _id: chatRoom._id },
{
$set: {
'lastMessage._id': chatMessage._id,
'lastMessage.chatRoomId': chatMessage.chatRoomId,
'lastMessage.createdBy': chatMessage.createdBy,
...
},
},
{ new: true, runValidators: true },
);
};
但由于某种原因,findOneAndUpdate 会为子文档字段抛出 path *propName* is required 错误。
"errors": {
"lastMessage.chatRoomId": {
"message": "Path `chatRoomId` is required.",
"name": "ValidatorError",
"properties": {
"message": "Path `chatRoomId` is required.",
"type": "required",
"path": "chatRoomId",
"value": "5f72f8666144a40bb15f368a"
},
"kind": "required",
"path": "lastMessage.chatRoomId",
"value": "5f72f8666144a40bb15f368a"
},
"lastMessage.createdBy": {
"message": "Path `createdBy` is required.",
"name": "ValidatorError",
"properties": {
"message": "Path `createdBy` is required.",
"type": "required",
"path": "createdBy",
"value": "5ec65435dd1b860d9898609b"
},
"kind": "required",
"path": "lastMessage.createdBy",
"value": "5ec65435dd1b860d9898609b"
}
},
"message": "Validation failed: lastMessage.chatRoomId: Path `chatRoomId` is required., lastMessage.createdBy: Path `createdBy` is required.",
令人困惑的部分是:
- 它只抛出
type: Schema.Types.ObjectId的字段(在此示例中为lastMessage.message道具通过验证); - mongoose
save方法不会抛出; - 它不会抛出正在使用子路径字段;
这是预期的猫鼬行为吗?如果有什么方法可以让它在不更新每个子文档字段或不保存方法的情况下工作?
谢谢!
【问题讨论】:
标签: javascript mongoose mongoose-schema