如果未找到 ID,则 Mongoose 更新文档或插入新文档(Express REST API)
Posted
技术标签:
【中文标题】如果未找到 ID,则 Mongoose 更新文档或插入新文档(Express REST API)【英文标题】:Mongoose Update Document or Insert New Document if ID Is Not Found (Express REST API) 【发布时间】:2017-11-27 11:12:05 【问题描述】:我已经设置了一个 Express REST Api,并希望实现一个检查某个对象 ID 是否存在的任务。
如果 Mongo 数据库中存在该 ID,我想使用 Put 请求更新此文档。这部分已经在我的代码中工作了。
如果数据库中尚不存在该 ID,我想创建一个新文档。为此,我尝试将“upsert”选项设置为 true,但如果我现在向一个 ID 发出 put 请求,该 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
字段的ObjectId
类型无效,您将其作为您的查询提供陈述。因此,您要么使用不正确的值进行调用,要么实际上是要匹配 _id
字段以外的另一个属性。您的架构仅显示name
和隐含的_id
,因此它可能只是一个不正确的值。您能显示您希望更新的实际数据库对象吗?另一个考虑是架构是错误的,需要为_id
定义一个String
。
【参考方案1】:
发生此错误是因为您定义了没有“_id”的事件架构,因此默认情况下“_id”属性的类型变为“ObjectId”,然后当您尝试使用此值“34455ab67”发送“_id”时,猫鼬方法尝试了将其转换为“ObjectId”类型,但它是无效的字符串。所以你应该做以下事情:
-
为“_id”属性发送有效的字符串值。
在将输入字符串转换为“ObjectId”之前验证输入字符串。
如果输入字符串有效,将其转换为“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”类型定义“_id”以简化此过程,但这取决于您的需要。
【讨论】:
该错误实际上发生了,因为 mongoose 已经在尝试“自动转换”到ObjectId
,因为这是为提供参数的属性定义的类型。因此,错误的真正原因是输入“字符串”甚至不是要转换为ObjectId
的有效数据,正如错误消息中所证明的那样。因此,尝试强制转换的“显式”只会导致相同的错误,因此不能解决这里的问题。
另一点,我们可以使用简单的正则表达式来验证输入字符串,而不是使用“ObjectId.isValid”,因为如果找到它也接受与 ObjectId 格式不匹配的字符串值!我会用这些更新来更新我的答案,以便更清楚
在模式中将 _id 定义为字符串并覆盖对象 id 后,它起作用了。非常感谢以上是关于如果未找到 ID,则 Mongoose 更新文档或插入新文档(Express REST API)的主要内容,如果未能解决你的问题,请参考以下文章