Mongodb 更新文档时获取文档的旧版本和新版本
对于我的应用程序在MongoDB上执行的每个操作,我希望文档的旧版本和新版本都相同,这样我就可以用这两个版本发出一个事件:Mongodb 更新文档时获取文档的旧版本和新版本,mongodb,mongoose,node-mongodb-native,Mongodb,Mongoose,Node Mongodb Native,对于我的应用程序在MongoDB上执行的每个操作,我希望文档的旧版本和新版本都相同,这样我就可以用这两个版本发出一个事件: { type: 'UPDATE', before: documentBeforeUpdate, after: documentAfterUpdate } 我现在这样做的方法是首先对查询发出findOne,然后对更新执行findOneAndUpdate,但使用文档的\u id进行查询。因此,如果查询实际上是在数据库上引发负载,我不会为此付出两次代价: async
{
type: 'UPDATE',
before: documentBeforeUpdate,
after: documentAfterUpdate
}
我现在这样做的方法是首先对查询发出findOne
,然后对更新执行findOneAndUpdate
,但使用文档的\u id
进行查询。因此,如果查询实际上是在数据库上引发负载,我不会为此付出两次代价:
async function updateOne(query, updates) {
const oldDocument = await this.model
.findOne(query, null, { lean: true })
.exec();
if (!oldDocument) {
return;
}
const newDocument = await this.model
.findOneAndUpdate({ _id: oldDocument._id }, updates, {
new: true,
lean: true
})
.exec();
// document vanished before it could be updated
if (!newDocument) {
return;
}
await this.emit("UPDATE", {
before: oldDocument,
after: newDocument,
type: "UPDATE"
});
return newDocument;
}
我有类似的函数用于updateMany
,delete{One,Many}
,createOne
等
现在我的问题是,是否有比这更有效的方法
上下文
我想做的是,为了查询性能的原因,将数据库中的数据去规范化的代码解耦。假设我有一个可以在餐厅预订桌子的应用程序,那么我希望预订在自己的集合中,但我也希望将每个桌子的可用性信息缓存在桌子自己的文档中。因此,我可以查询表集合中特定时间可用的表
// reservation
{
_id: ObjectId,
table: ObjectId,
from: Date,
to: Date
}
// table
{
_id: ObjectId,
reservations: [
{ _id: ObjectId, from: Date, to: Date },
// ...
]
}
如果有一个事件系统,我可以监听文档的创建、更新和删除,我不需要直接从更新保留文档的代码调用更新表的保留属性的代码。这就是我想要实现的体系结构。FindDoneUpdate中有一个名为 returnNewDocument:boolean 此选项将告诉mongodb返回旧文档,而不是在响应对象中返回更新的文档 来自mongo文档
db.collection.findOneAndUpdate(filter, update, options)
根据筛选和排序条件更新单个文档
findOneAndUpdate()方法具有以下形式:
db.collection.findOneAndUpdate(
<filter>,
<update>,
{
projection: <document>,
sort: <document>,
maxTimeMS: <number>,
upsert: <boolean>,
returnNewDocument: <boolean>,
collation: <document>
}
)
db.collection.findOneAndUpdate(
,
,
{
投影:,
排序:,
maxTimeMS:,
插入:,
returnNewDocument:,
整理:
}
)
您的代码不适用:
名为“updates”并传递给FindUpdateOne的更新对象应包含字段{returnNewDocument:true},
然后您需要从FindUpdateOne方法读取响应,这样您就可以在不运行单独的findOne查询的情况下获得旧文档
Mongo手册-findOneAndUpdate
AFAIK OP希望接收带有findOneAndUpdate的原始和新文档。这个答案表明,将returnNewDocument:true作为更新对象的一部分传递(而不是选项-因此我们可能会覆盖文档本身中的字段“returnNewDocument”)将返回原始文档和新文档?这似乎不对,你能详细说明一下吗?