如何使用基于 _id 的 Mongoose 进行 upsert?
Posted
技术标签:
【中文标题】如何使用基于 _id 的 Mongoose 进行 upsert?【英文标题】:How can I upsert using Mongoose based on _id? 【发布时间】:2012-01-19 09:40:55 【问题描述】:当我这样做时:
client_id = req.param("client_id") ? null
client =
name: req.param "clientName"
status: 'active'
Client.update _id: client_id, client, upsert: true, (err, updRes) ->
if err
res.json
error: "Couldn't create client"
else
res.json client
它将创建一个新的客户记录,但 null
_id
字段除外。我认为这是因为 upsert 的插入部分看起来是 query
来创建文档。我该怎么做才能在没有找到文档的情况下插入一个新的ObjectId
?
【问题讨论】:
【参考方案1】:不确定你是否已经想出了这个,但如果你不想遇到像上面提到的 Mustafa 这样的唯一键约束的问题,我这样做的方法是使用猫鼬的findByIdAndUpdate:
// require mongoose
client_id = req.param("client_id") ? new mongoose.Types.ObjectId
client =
name: req.param "clientName"
status: 'active'
Client.findByIdAndUpdate client_id, client, upsert: true, (err, updRes) ->
if err
res.json
error: "Couldn't create client"
else
res.json client
我从未编写过 CoffeeScript,如果其中一些语法错误,请原谅我,但我认为我正在尝试做的事情应该是相当明显的。
需要注意的一点是,您需要确保 client_id 既不是空字符串(因为这会导致“无效 ObjectID”错误)也不是空字符串(因为 mongoose 似乎从您正在查询的文档中推断出新文档的 id为了)。如果是这样,我会创建一个新的 ObjectId,这将导致查询丢失,因此会创建一个具有该 ID 的新文档,因为我通过了 upsert: true。
这似乎为我解决了问题。
【讨论】:
在 Mongoose v 4.0 之后,您需要将new
选项显式设置为 true
,因为 4.0 之前的默认值是 true
,但现在在 4.0 之后是 false
。参考this stack overflow question 和these release notes。【参考方案2】:
您对 Mongoose 所做的只是在客户端调用 save,Mongoose 会自行判断是更新还是插入:
client_id = req.param("client_id") ? null
client_data =
name: req.param "clientName"
status: 'active'
_id: client_id
client = new Client(client_data)
client.save (err) ->
if err
res.json
error: "Couldn't save client"
else
res.json client
注意:客户端是 Mongoose 模型。
【讨论】:
所以不再需要 upserts 了吗? 我可以告诉你我已经在我的代码中实际使用了它,用于插入和更新,它可以工作,所以不需要 upserts。祝福猫鼬 ODM :) 如果 client_id 为空,是否会使用新的_id
保存?
你能解释更多吗,@Mustafa?
确认这在索引字段上失败。参考:groups.google.com/forum/?fromgroups=#!topic/mongoose-orm/…以上是关于如何使用基于 _id 的 Mongoose 进行 upsert?的主要内容,如果未能解决你的问题,请参考以下文章
Mongoose - 如何防止 mongoose 在模型实例化时创建 _id