如何从MongoDB嵌套数组中获取对象

时间:2020-08-17 13:45:00

标签: javascript mongodb

我有一个MongoDB集合,用于存储聊天对象,消息嵌入为嵌套数组。整个集合如下所示:

chats = [
  {
    _id: 0,
    messages: [
      {
        _id: 0,
        text: 'First message'
      },
      {
        _id: 1,
        text: 'Second message'
      }
    ]
  },
  {
    _id: 1,
    messages: []
  }
]

我想更新一条消息并将其返回给用户。我可以这样更新消息(在Node中):

const chat = chats.findOneAndUpdate({
        _id: ObjectId(chatID),
        "messages._id": ObjectId(messageID)
    }, {
        $set: {
            "messages.$.text": newText
        }
    });

问题是此查询更新一条消息并返回一个聊天对象,这意味着我必须再次在代码中查找更新的消息。 (即chat.messages.find(message => message._id === messageID))。

是否可以直接从MongoDB获取消息对象?在同一个查询中进行更新也将很不错。

编辑:我在Mongodb中使用Node。

谢谢!

1 个答案:

答案 0 :(得分:0)

由于MongoDB方法findOneAndUpdatefindAndModify不允许从数组字段获取更新的文档,

  • 投影将在数组字段名称后使用位置$返回数组的更新后的子文档
  • returnNewDocument: true将返回更新的(新)文档,但这将返回整个文档对象

问题是,MongoDB无法允许使用位置投影并一起返回新文档

用于临时解决方案 尝试使用projection,这将使用$位置从数组字段返回原始文档,

const chat = chats.findOneAndUpdate(
  {
    _id: ObjectId(chatID),
    "messages._id": ObjectId(messageID)
  }, 
  { $set: { "messages.$.text": newText } },
  { 
    projection: { "messages.$": 1 }
  }
);

结果:

{
    "_id" : 0.0,
    "messages" : [ 
        {
            "_id" : 0.0,
            "text" : "Original Message"
        }
    ]
}

要获取更新的文档,可以这样进行新的查询:

const message = chats.findOne({
    _id: ObjectId(chatID),
    "messages._id": ObjectId(messageID)
  }, {
    projection: {'messages.$': 1},
}).messages[0];

结果:

{
    "_id": 0.0,
    "text": "New message",
}