繁体   English   中英

MongoDB-Mongoose:如何使用Mongoose同时更新两个单独的嵌入式文档?

[英]MongoDB - Mongoose: How Do I Update Simultaneously Two Separate Embedded Documents With Mongoose?

因此,我试图通过一个API调用来更新Report文档和Station.reports子文档中的字段status ,该子文档是一组对象。 问题是在进行API调用时,我能够更新Report文档,但不能更新Station文档。 通话结束后, console.log(station.reports); 返回期望的子文档: [{"_id":"588fed278b50cd180bd6cc15","date":"2017-01-31T01:48:57.487Z","status":"Archived"}]但这未保存在我的数据库中相应的Station文档。 请在这里我需要帮助。 谢谢。

车站文件:

{
    "_id": "588a777d4e26720e7afa7e1e",
    "phone": "(007) – 007 – 7007",
    "name": "name1",
    "email": "name1@email.com",
    "reports": [
      {
        "status": "Submitted",
        "date": "2014-01-31T01:48:57.487Z",
        "_id": "588fed278b50cd180bd6cc15"
      }
    ]
}  

报告文件

{
    "_id": "588fed278b50cd180bd6cc15",
    "description": "Description of the report",
    "time": "05:48 PM",
    "date": "2017-01-31T01:48:57.487Z",
    "status": "Archived",
    "location" : "123 Main Street"
    "station" : "588a777d4e26720e7afa7e1e"
}  

API调用

router.put('/reports/:id/updateStatus', function (req, res) {

    Report.findById(req.params.id, function(err,report){
        // if there is an error retrieving, send the error.
        // nothing after res.send(err) will execute
        if (err)
          return res.send(err);

        //  Update the Report object 
        report.status = req.body.status;

        // Update the Corresponding station.reports subdocument
        Station.findOne({_id:report.station}, function (err, data) {
            if(err) return console.log(err);

            data.reports.forEach(function(rpt){
                if (rpt._id == req.params.id){

                    rpt.status = req.body.status
                    data.save(function (err, station) {
                        if (err)
                            return res.send(err); 

                        console.log(station.reports);
                    })
                }
            })
        })

        report.save(function (err, report) {
            if (err)
                return res.send(err); 

            res.json(report);
        })
    });
})

更新station对象时出错。 使用findOneAndUpdate查找匹配的Station文档,然后更改匹配的报告项目(使用reports._id进行匹配)的状态。

尝试这个:

Station.findOneAndUpdate({
        _id:report.station,"reports._id":req.params.id
    },{
        $set : {reports.$.status : req.body.status}
    },function(err){
    if(err)
        return res.send(err);
});

report._id将找到_idreq.params.id的数组元素, report.$.status将仅更新数组的匹配元素。

有关positional $(update) operator更多信息,请阅读mongoDB位置文档

另外,我建议save report对象savecallback of updatecallback of update 由于nodejsasynchronous ,因此,如果您将report保存在回调之外,它将不等待update完成。 而且,你可能会得到广东话设置的标头发送之后 error 因此,建议在回调中执行此操作。

因此,您最终的API代码如下所示:

router.put('/reports/:id/updateStatus', function (req, res) {

    Report.findById(req.params.id, function(err,report){
        // if there is an error retrieving, send the error.
        // nothing after res.send(err) will execute
        if (err)
          return res.send(err);

        //  Update the Report object 
        report.status = req.body.status;

        // Update the Corresponding station.reports subdocument
        Station.findOneAndUpdate({
                "_id":report.station,"reports._id":req.params.id
            },{
                $set : {"reports.$.status" : req.body.status}
            },function(err, result){
                if(err)
                    return res.send(err);
                console.log(result);
                report.save(function (err, report) {
                    if (err)
                        return res.send(err); 

                    res.json(report);
                });
        });
    });
})

UPDATE 备用方法

另一种方法是,您可以按原始方式进行操作,但不要将数据保存在forEach内部,而是保存数据表forEach完成。

Station.findOne({_id:report.station}, function (err, data) {
    if(err) return console.log(err);

    data.reports.forEach(function(rpt){
        if (rpt._id == req.params.id){

            rpt.status = req.body.status
        }
    });
    data.save(function (err, station) {
        if (err)
            return res.send(err); 

        console.log(station.reports);
        report.save(function (err, report) {
            if (err)
                return res.send(err);
            res.json(report);
        });
    })
})

希望这可以帮助!

经过多次尝试,并在Ravi的帮助下,我找到了一个对我来说非常有效的解决方案。 唯一改变的是我的API调用。 其余代码未更改。
希望这可以帮助有类似需求的人。

API呼叫

router.put('/reports/:id/updateStatus', function (req, res) {

    Report.findById(req.params.id, function(err,report){
        // if there is an error retrieving, send the error.
        // nothing after res.send(err) will execute
        if (err)
          return res.send(err);

        //  Update the Report object 
        report.status = req.body.status;

        // Update the Corresponding station.reports subdocument
        Station.findOne({_id:report.station}, function (err, info) {
            if(err) return console.log(err);

            info.reports.forEach(function(rpt){
                if (rpt._id == req.params.id){

                    Station.update({_id:info._id, "reports._id":rpt._id },
                        {
                            $set:{"reports.$.status": req.body.status }
                        },function (err, results) {
                            if(err) return console.log("This Station couldn't be updated " + err);
                            console.log(results)
                        }
                    )
                }
            })
            report.save(function (err, report) {
                if (err)
                    return res.send(err); 

                res.json({report:report, station:info});
            });
        })
    });
})

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM