javascript-猫鼬-创建文档(如果不存在),否则,更新-在两个cas中返回文档

我正在寻找一种将代码的一部分重构为更短,更简单的方法,但是我对Mongoose不太了解,我不确定该如何进行。

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

到目前为止,我设法做到的是查询集合中的特定文档,如果找不到,则创建一个新文档。 如果找到它,我将对其进行更新(当前使用日期作为虚拟数据)。 从那里,我可以从最初的findOneAndUpdate操作中找到找到的文档,也可以访问新保存的文档,并且可以正常工作,但是必须有一种更好的方法来完成我要执行的操作。

这是我的工作代码,没有其他功能。

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和其他相关方法,但不确定它们是否适合我的用例或我是否知道如何正确使用它们。 谁能指出我正确的方向?

(大概)相关问题:

  • 如何在更新期间检查数据库中是否已存在数据(Mongoose And Express)
  • Mongoose.js:如何实现创建或更新?
  • NodeJS + Mongo:如果不存在则插入,否则-更新
  • 用猫鼬返回更新的集合

编辑

在搜索过程中,我没有遇到指向我的问题,但是在查看了答案之后,我想到了这个问题。 在我看来,它当然更漂亮,并且可以工作,因此,除非我做的事情很糟糕,否则我想我的问题可能会结束。

我很乐意在解决方案上提供任何其他意见。

// 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;
            }
        });
    }
});
Connor asked 2020-02-16T13:43:34Z
3个解决方案
89 votes

您正在寻找upsert选项参数。 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如果找不到文档,则会创建一个文档,因此您无需手动创建另一个文档。

answered 2020-02-16T13:43:57Z
6 votes

由于您希望将代码的一部分重构得更短,更简单,

  1. 使用.findOneAndUpdate()
  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);
Jossef Harush answered 2020-02-16T13:44:26Z
0 votes
///This is simple example explaining findByIDAndUpdate from my code added with try catch block to catch errors
try{
const options = {
            upsert: true,
            new: true,
            setDefaultsOnInsert: true
        };
        const query = {
            $set: {
                description: req.body.description,
                title: req.body.title
            }
        };
        const survey = await Survey.findByIdAndUpdate(
            req.params.id,
            query,
            options
        ).populate("questions");
}catch(e){
console.log(e)
}
Rahul Sadaphal answered 2020-02-16T13:44:41Z
translate from https://stackoverflow.com:/questions/33305623/mongoose-create-document-if-not-exists-otherwise-update-return-document-in