Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/420.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Mongoose-创建文档(如果不存在),否则,更新-在任何情况下返回文档_Javascript_Node.js_Mongoose_Refactoring - Fatal编程技术网

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

Javascript Mongoose-创建文档(如果不存在),否则,更新-在任何情况下返回文档,javascript,node.js,mongoose,refactoring,Javascript,Node.js,Mongoose,Refactoring,我正在寻找一种方法来重构我的部分代码,使之更短更简单,但我对Mongoose不太了解,也不知道如何继续 我试图检查一个集合是否存在文档,如果它不存在,就创建它。如果它确实存在,我需要更新它。无论哪种情况,我都需要在之后访问文档的内容 到目前为止,我所做的是查询集合中的特定文档,如果找不到,则创建一个新文档。如果找到了它,我会更新它(目前使用日期作为虚拟数据)。从那里,我可以从我最初的find操作中访问找到的文档,或者访问新保存的文档,这样做很有效,但必须有更好的方法来完成我所追求的目标 这是我的

我正在寻找一种方法来重构我的部分代码,使之更短更简单,但我对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;
            }
        });
    }
});

您正在查找
新的
选项参数。
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
会在找不到文档时创建一个文档,所以您不需要手动创建另一个文档。

因为您希望将部分代码重构为更短更简单

  • 使用
  • 按照本手册中的建议使用

  • 下面是一个例子:

    const mongoose=require('mongoose');
    猫鼬mongodb://localhost/rsvp“,{useNewUrlParser:true,useUnifiedTopology:true});
    const db=mongoose.connection;
    db.on('错误',()=>{
    log('mongoose连接错误');
    });
    db.one('打开',()=>{
    console.log('mongoose已成功连接');
    });
    const rsvpSchema=mongoose.Schema({
    名字:String,
    姓氏:String,
    电子邮件:String,
    客人:电话号码
    });
    const Rsvp=mongoose.model('Rsvp',rsvpSchema);
    //这是你需要的部分。。。在本例中,如果名字和姓氏匹配,则更新电子邮件和客人号码。否则,创建一个新文档。关键是要学会把“upsert”作为论点的“选项”。
    const findRsvpAndUpdate=(结果,回调)=>{
    Rsvp.findOneAndUpdate({firstName:result.firstName,lastName:result.lastName},result,{upsert:true},(err,results)=>{
    如果(错误){
    回调(err);
    }否则{
    回调(空,结果);
    }
    })
    };
    //从服务器index.js文件中,调用此。。。
    app.post('/rsvps',(请求、回复)=>{
    findRsvpAndUpdate(请求正文,(错误,结果)=>{
    如果(错误){
    资源状态(500)。发送(错误);
    }否则{
    资源状态(200)。发送(结果);
    }
    })
    
    });
    Que:Mongoose.js:如何实现创建或更新?老实说,我现在觉得自己很傻。我在搜索时没有发现这个问题,但回想起来,答案似乎很容易掌握。谢谢你的帮助!除了新创建的文档没有使用我的模式中定义的默认值填充之外,这似乎是可行的。非常混乱。你知道这是什么原因吗?@Connor是的,这是猫鼬的默认功能,尽管有一个选项可以解决这个问题。检查我的最新答案。有点奇怪,但我认为开发人员有他们的理由。这是一个非常好的解决我的问题的方法,所以谢谢你的帮助!在这种情况下,您如何识别发送的状态代码?200=已更新。201 createdWhat如果我试图更新的对象有一个id列表,并且我想向其中添加一个新id?这将替换或添加到列表中吗?如果您使用api获取json中的项目,并希望使用模型执行以下操作:让update=json.parse(data);别忘了用try&catch:)来结束它
    let query = { /* query */ };
    let update = {expire: new Date()};
    let options = {upsert: true, new: true, setDefaultsOnInsert: true};
    let model = await Model.findOneAndUpdate(query, update, options);
    
    ///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)
    }