Javascript MongoDB-Mongoose:如何使用Mongoose同时更新两个独立的嵌入式文档?
因此,我试图在一次API调用中更新myJavascript MongoDB-Mongoose:如何使用Mongoose同时更新两个独立的嵌入式文档?,javascript,node.js,mongodb,api,mongoose,Javascript,Node.js,Mongodb,Api,Mongoose,因此,我试图在一次API调用中更新myReport文档和myStation.reports子文档中的字段status,它是一个对象数组。问题是,在进行API调用时,我能够更新报告文档,但不能更新station文档。调用后,console.log(station.reports)返回预期的子文档,该子文档是:[{{U id:“588fed278b50cd180bd6cc15”,“日期”:“2017-01-31T01:48:57.487Z”,“状态”:“存档”}],但它不会保存在my DB中的相应站
Report
文档和myStation.reports
子文档中的字段status
,它是一个对象数组。问题是,在进行API调用时,我能够更新报告文档,但不能更新station文档。调用后,console.log(station.reports)
返回预期的子文档,该子文档是:[{{U id:“588fed278b50cd180bd6cc15”,“日期”:“2017-01-31T01:48:57.487Z”,“状态”:“存档”}]
,但它不会保存在my DB中的相应站点文档中。求求你,我需要帮助。谢谢
电台文件:
{
"_id": "588a777d4e26720e7afa7e1e",
"phone": "(007) – 007 – 7007",
"name": "name1",
"email": "name1@email.com",
"reports": [
{
"status": "Submitted",
"date": "2014-01-31T01:48:57.487Z",
"_id": "588fed278b50cd180bd6cc15"
}
]
}
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});
});
})
});
})
报告文档
{
"_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"
}
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);
})
});
})
API调用
{
"_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"
}
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);
})
});
})
更新
站点
对象时出错。使用findOneAndUpdate
查找匹配的站点
文档,然后更改匹配报告项的状态(使用报告进行匹配。\u 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.\u id
将查找其\u id
为req.params.id
和report的数组元素。$。status
将仅更新数组的匹配元素
有关位置$(更新)运算符的详细信息,请阅读
另外,我建议在更新的回调中保存报告对象。由于nodejs
是asynchronous
,如果您在回调之外保存报告
,它将不会等待更新
完成。而且,您可能会收到发送后无法设置标题的消息错误
。因此,建议在回调中执行此操作
因此,您的最终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);
});
});
});
})
更新
替代方法
另一种方式可以是,您可以按原始方式继续,但不要将数据保存在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);
});
})
})
希望这有帮助 在多次尝试之后,在拉维的帮助下,我找到了一个对我非常有效的解决方案。唯一改变的是我的API
调用。代码的其余部分保持不变。
希望这能帮助有类似需求的人
API调用
{
"_id": "588a777d4e26720e7afa7e1e",
"phone": "(007) – 007 – 7007",
"name": "name1",
"email": "name1@email.com",
"reports": [
{
"status": "Submitted",
"date": "2014-01-31T01:48:57.487Z",
"_id": "588fed278b50cd180bd6cc15"
}
]
}
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});
});
})
});
})
嗨,拉维。谢谢你的回复。我想尝试一下您的建议,但是首先考虑到子文档reports
是一个数组,您如何可能编写报告。这可能会破坏整个局面,对吗?可能我遗漏了什么不不,你可以像那样在数组中查询,然后报告。$.status
将真正只更新报告数组中匹配的元素。我不知道这个技巧。好啊让我现在就试试。试过了,但没用。仍然会更新报告
对象,但不会更新站点.报告
子文档。我甚至尝试了$push
而不是$set
没有luckCan可以检查是否有错误,但我认为我编辑的答案应该有效。