Mongoosejs 刷新文档

Posted

技术标签:

【中文标题】Mongoosejs 刷新文档【英文标题】:Mongoosejs refresh a document 【发布时间】:2012-12-07 07:57:33 【问题描述】:

假设我有一个文档,例如: var doc = Model.findOne(name:"name");

现在,如果文档通过数据库的另一个连接进行编辑,则 doc 不包含正确的信息。我确实需要它,所以我必须从数据库中“刷新”或“重新下载”它。有没有办法只使用对象“doc”来做到这一点?

【问题讨论】:

如果要更新当前对象,可以使用 findAndModify 命令。你有什么要求? 假设我有两台服务器正在运行,它们不断修改数据库并需要最新信息,但它们只有文档。 好的,如果我正确理解您的要求,如果您只需要更新文档,那么您必须使用 findAndModify API 来更新最新的文档。如果您想做其他方式,那么您必须在文档中使用一些锁定字段自定义代码。 您能否解释得更好一些,因为我不明白。我应该使用什么“doc”方法? 检查this solution。 【参考方案1】:

假设doc 包含要刷新的文档实例,您可以这样做以进行一般刷新:

doc.model(doc.constructor.modelName).findOne(_id: doc._id,
    function(err, newDoc) 
        if (!err) 
            doc = newDoc;
        
    
);

但是,最好不要持久化/缓存 Mongoose 文档实例超出您对它们的迫切需要。缓存您需要快速访问的不可变文档_id,而不是文档本身。

【讨论】:

【参考方案2】:

抱歉,我知道这是旧的,但我有一个更好的解决方案,以防其他人仍在四处寻找。

在这种并发访问同一文档的情况下,您可以执行正常保存。

Mongoose 使用对象的 __v 属性来确保旧实例不会覆盖最新实例。

因此,如果您有 2 个 doc.__v = 0 实例,并且 A 先保存,则数据库现在具有 doc.__v = 1。因此,当 B 保存时,它会出错,因为 B.__v = 0,而不是1.所以你可以做的是捕捉错误(它应该是一个特定的猫鼬错误)并通过刷新对象来处理它,(它应该将它提升到 __v = 1)然后保存或不保存它取决于你想做什么。

在代码中

doc.save(function (err, _doc) 
    if (err) 
        if (err.some_error_property_telling_you_version_was_wrong) 
            // Do your business here 
            // Refresh your object
            // Model.findById(doc._id, function (err, _refreshed_doc) );
            // doc = _refreshed_doc;
            // doc.set('property', value); set the value again
            // Then re-save? or maybe make this a recursive function,
            // so it can keep trying to save the object?
         else 
            // Handle it like a normal error
        
    
);  

【讨论】:

【参考方案3】:

如果它是用let 定义的,你可以这样做

await thing.update(stuff);
thing = await Thing.findById(thing._id);

或者如果是const,那么就一成不变:

await thing.update(stuff);
const updatedThing = await Thing.findById(thing._id);

【讨论】:

以上是关于Mongoosejs 刷新文档的主要内容,如果未能解决你的问题,请参考以下文章

Mongoosejs 更新子文档

为啥使用 Mongoose JS 删除嵌入式子文档数组的元素不起作用?

Mongoosejs - 我可以在“查找”的后查询中间件中修改文档吗?

Mongoose 子文档排序

Mongoose 嵌入文档/DocumentsArrays id

Mongoose 参考儿童