我正在处理包含多个消息的对话集合。
向对话中添加新消息时,我想为每条消息创建一个属性messageIndex
,该属性是为每条新消息动态设置或递增的。
(为简便起见,以下示例中的文档ID均已替换)。
我想要获得的结果是:
// conversation document
{
_id: "C1",
messageCount: 3,
lastMessage: { sender: "U2", content: "I am Stephen", messageIndex: 3 },
messages: [
{ sender: "U1", content: "Hello", messageIndex: 0 },
{ sender: "U1", content: "I'm Bob", messageIndex: 1 },
{ sender: "U2", content: "Hi there!", messageIndex: 2 },
{ sender: "U2", content: "I am Stephen", messageIndex: 3 }
]
}
我得到的是什么
// conversation document
{
_id: "C1",
messageCount: 3,
lastMessage: { sender: "U2", content: "I am Stephen", messageIndex: 0 },
messages: [
{ sender: "U1", content: "Hello", messageIndex: 0 },
{ sender: "U1", content: "I'm Bob", messageIndex: 0 },
{ sender: "U2", content: "Hi there!", messageIndex: 0 },
{ sender: "U2", content: "I am Stephen", messageIndex: 0 }
]
}
我想知道是否有可能为创建的每个新子文档动态地增加字段(通过运行单个更新查询)。
否则,是否有可能使新创建的子文档引用父文档中的值(通过运行单个更新查询)。
我的方法是尝试引用现有(父)文档中的值。
这是我的更新查询,我将新消息推送到messages
字段。
const addNewMessage = async (conversationId, contentStr, userId) => {
const message = { content: contentStr, sender: userId }
const updated = await ConversationModel.findOneAndUpdate(
{ _id: conversationId },
{
$push: { messages: message },
$inc: { messageCount: 1 },
lastMessage: message
},
{ new: true }
);
return updated;
};
这是我的带有子架构的模型。
conversation-model.js
import mongoose from "mongoose";
const { Schema } = mongoose;
// sub schema
const Message = new Schema(
{
sender: ObjectId,
content: String,
messageIndex: {
type: Number,
default: function() {
console.log('\n this: ', this);
if (!this.messageCount) return 0;
else return this.messageCount;
// if `messageCount` is 0 or not set, set the message index to `0` - first message
// else set the `messageIndex` using the `messageCount` from the conversation document
}
}
}
);
// Conversation Model
const conversationSchema = new Schema(
{
messageCount: { type: Number, min: 1 },
lastMessage: Message,
messages: [ Message ]
}
);
const Conversation = mongoose.model("Conversation", conversationSchema);
module.exports = Conversation;
我可以首先通过findById()
获取对话文档,然后使用.save()
运行更新并插入新消息。
但是,我想知道是否可以通过仅运行一个更新查询来做到这一点?