Mongoose更新文档或插入新文档如果没有findID(Express REST API)

我已经build立了一个Express REST Api,并且想实现一个检查某个对象ID是否存在的任务。

如果该ID存在于Mongo数据库中,我想使用Put请求来更新这个文档。 这部分已经在我的代码中工作。

如果ID尚不存在于数据库中,我想创build一个新的文档。 要做到这一点,我试图将“upsert”选项设置为true,但是,如果我现在做一个ID的放入请求,这是不是在我的数据库,但它回来的错误:

throw er; // Unhandled 'error' event ^ CastError: Cast to ObjectId failed for value "34455ab67" at path "_id" for model "event" 

这里是我的事件模型代码:

 var mongoose = require('mongoose'); var eventSchema = mongoose.Schema({ name: { type: String, required: true } }); var Events = module.exports = mongoose.model('event', eventSchema, 'event'); module.exports.updateEvent = function (id, event, options, callback) { var query = {_id : id}; var update = { name: event.name, }; Events.findOneAndUpdate(query, update, options, callback); }; 

这是REST API调用

 app.put('/api/event/:_id', function(req, res) { var id = req.params._id; var event = req.body; var options = { upsert: true, new: true, setDefaultsOnInsert: true }; Events.updateEvent(id, event, options, function(err, event){ if(err){ trow err; } res.json(event); }) }); 

任何帮助将不胜感激!

发生这个错误的原因是你定义的事件模式没有“_id”,所以默认的“_id”属性的types变成了“ObjectId”,然后当你试图发送带这个值的“_id”时,mongoose方法试图对其进行转换到“ObjectId”types,但它是无效的string。 所以你应该做到以下几点:

  1. 为“_id”属性发送有效的string值。
  2. 在将其转换为“ObjectId”之前validationinputstring。
  3. 如果inputstring有效,则将其转换为“ObjectId”,然后在mongoose查询中使用它。

检查下面的例子:

 var mongoose = require('mongoose'); //inputId is the input string passed from the front end if (inputId.match(/^[0-9a-fA-F]{24}$/)) { // it's a valid string to be converted to "ObjectId" var id = mongoose.Types.ObjectId(inputId); //then use this id in your mongoose queries. } else { //Not valid } 

或者你可以用“String”types来定义“_id”来简化这个过程,但这取决于你的需要。