我创建了一个nodejs API,你可以通过POST推送新的条目,如果条目已经存在,它应该更新它。
现在我遇到的问题是我从mongoose通过findOne()
检查该条目是否已存在,但它不会触发更新功能。
这是代码:
通过POST进入点:
exports.create_a_status = function(req, res) {
if(read_status(req.body.hostname)){
console.log("update")
update(req,res)
}
else{
var new_status = new Status(req.body);
new_status.save(function(err, status) {
if (err)
res.send(err);
history.create_a_history(req.body);
res.json(status);
});
}
}
检查条目是否存在:
const read_status = function(hostname){
Status.findOne({hostname: hostname},function(err,status){
console.log(hostname)
if (status){
console.log(status)
return status;
}
return;
})
}
和更新功能,但这不会从create_a_status()
:
exports.update = function(req, res) {
// Update a status identified by the hostname in the request
Status.findOneAndUpdate({hostname: req.params.hostname}, req.body,{new:true})
.then((updatedStatus) => {
res.json(updatedStatus);
})
.catch((err)=>{
res.send(err);
});
};
提前致谢!
答案 0 :(得分:0)
我会尝试以下内容。 可以使用回调而不是promises来编写相同的结构。或者不使用promisify()并将回调包装在您自己的新Promise()调用中。那就是更多的代码。
// PROMISES VERSION
// We can import the promisify function from node util to turn our callbacks into promises.
const { promisify } = require( 'util' );
// Check if status exists.
// If exists, update it. Else create new status and new history.
// If anything throws an error, send it as the response.
const create_a_status = function( request, response ) {
Promise
.resolve( request.body.hostname )
.then( host => read_status( { host } ) )
.then( status => status ? update_status( { 'hostname' : request.params.hostname, 'body' : request.body, 'new' : true } ) : new_status( request.body ) )
.then( status => response.json( status ) );
.catch( error => response.send( error ) );
/* Depending on the function scopes, we might be able to omit all the x => y(x) calls.
Promise
.resolve( { 'host' : request.body.hostname } )
.then( read_status )
.then( status => status ? update_status( { 'hostname' : request.params.hostname, 'body' : request.body, 'new' : true } ) : new_status( request.body ) )
.then( response.json );
.catch( response.send );
*/
};
// Since we just need to return the status or error, we can just promisify the findOne method.
const read_status = promisify( Status.findOne.bind( Status ) );
// Since we just need to run the function and return, the .then().catch() in the create_a_status function will also fix this.
const update_status = promisify( Status.findOneAndUpdate.bind( Status ) );
const new_status = function( body ) {
const status = new Status( body );
const save = promisify( status.save.bind( status ) );
return save
.then( status => {
history.create_a_history( body );
return status;
} );
};
答案 1 :(得分:0)
我解决了它:
exports.update_a_status = function(req, res) {
// Update a status identified by the hostname in the request
Status.findOneAndUpdate({hostname: req.body.hostname}, req.body,{upsert: true, new: true, runValidators: true})
.then((updatedStatus) => {
res.json(updatedStatus);
})
.catch((err)=>{
res.send(err);
});
};
关键是findOneAndUpdate()
函数中我没有设置upsert: true
的选项是什么意思,如果它确实通过主机名找到一个条目,它只会创建它。