猫鼬:在更新现有文档时在子文档上创建动态索引

时间:2020-03-09 00:07:43

标签: mongoose indexing dynamic nested schema

我正在处理包含多个消息的对话集合。

向对话中添加新消息时,我想为每条消息创建一个属性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()运行更新并插入新消息。
但是,我想知道是否可以通过仅运行一个更新查询来做到这一点?


0 个答案:

没有答案