Mongoose - 如果文档不存在,创建文档,否则更新文档 - 在任何一种情况下返回文档

27 浏览
0 Comments

Mongoose - 如果文档不存在,创建文档,否则更新文档 - 在任何一种情况下返回文档

我正在寻找一种方式来重构我的代码部分,使其更短、更简单,但我不太熟悉 Mongoose,也不确定如何继续下去。

我正在尝试检查集合是否存在文档,如果不存在,则创建它。如果存在,则需要更新它。无论哪种情况,我都需要在之后访问文档内容。

到目前为止,我已经成功查询集合以查找特定文档,并且如果找不到,创建一个新文档。如果发现它,我会更新它(目前使用日期作为虚拟数据)。从那里,我可以访问最初的 find 操作找到的文档或者新保存的文档,这是有效的,但肯定有更好的方法来实现我想要的功能。

这是我的工作代码,去掉了干扰性的附加内容。

var query = Model.find({
    /* query */
}).lean().limit(1);
// Find the document
query.exec(function(error, result) {
    if (error) { throw error; }
    // If the document doesn't exist
    if (!result.length) {
        // Create a new one
        var model = new Model(); //use the defaults in the schema
        model.save(function(error) {
            if (error) { throw error; }
            // do something with the document here
        });
    }
    // If the document does exist
    else {
        // Update it
        var query = { /* query */ },
            update = {},
            options = {};
        Model.update(query, update, options, function(error) {
            if (error) { throw error; }
            // do the same something with the document here
            // in this case, using result[0] from the topmost query
        });
    }
});

我已研究了 findOneAndUpdate 和其他相关方法,但我不确定它们是否适合我的使用情况,或者我是否理解如何正确使用它们。有谁能指点我正确的方向吗?

(可能)相关问题:


编辑

在我的搜索中,我没有找到指出的问题,但是在查看那里的答案后,我想出了这个。在我看来,它肯定更漂亮,并且它有效,因此,除非我做了什么极其错误的事情,我认为我的问题可能已经可以关闭了。

我将非常感谢您对我的解决方案提供任何额外的意见。

// Setup stuff
var query = { /* query */ },
    update = { expire: new Date() },
    options = { upsert: true };
// Find the document
Model.findOneAndUpdate(query, update, options, function(error, result) {
    if (!error) {
        // If the document doesn't exist
        if (!result) {
            // Create it
            result = new Model();
        }
        // Save the document
        result.save(function(error) {
            if (!error) {
                // Do something with the document
            } else {
                throw error;
            }
        });
    }
});

admin 更改状态以发布 2023年5月22日
0
0 Comments

既然您希望重构您的代码的部分,使它们更短,更简单,

  1. 使用 async/await
  2. 使用 .findOneAndUpdate(),如在此 答案中建议的那样。

let query = { /* query */ };
let update = {expire: new Date()};
let options = {upsert: true, new: true, setDefaultsOnInsert: true};
let model = await Model.findOneAndUpdate(query, update, options);

0
0 Comments

你正在寻找 new 选项参数。 new 选项返回新创建的文档(如果创建了新文档)。使用它的方法如下:

var query = {},
    update = { expire: new Date() },
    options = { upsert: true, new: true, setDefaultsOnInsert: true };
// Find the document
Model.findOneAndUpdate(query, update, options, function(error, result) {
    if (error) return;
    // do something with the document
});

由于 upsert 如果没有找到文档,则创建文档,因此您不需要手动创建另一个文档。

0