9

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

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

4

3 回答 3

7

假设doc包含要刷新的文档实例,您可以执行此操作来一般刷新它:

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

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

于 2012-12-19T22:14:57.847 回答
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
        }
    }
});  
于 2016-02-26T17:26:37.270 回答
1

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

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

或者如果是这样,const那么就一成不变地这样做:

await thing.update(stuff);
const updatedThing = await Thing.findById(thing._id);
于 2021-06-28T00:20:26.793 回答