【发布时间】:2012-08-22 21:36:10
【问题描述】:
我正在使用 Mongoose 执行以下操作:
that.model.update({_id: dao._id}, dao, { upsert: true }, cb);
dao 是一个包含(除其他外)几个嵌入文档的猫鼬表示。作为测试,我在调用上面的更新方法之前从数组中删除了几个嵌入式文档。
结果是对嵌入式文档数组的更改未保留。
我忽略了什么?
【问题讨论】:
我正在使用 Mongoose 执行以下操作:
that.model.update({_id: dao._id}, dao, { upsert: true }, cb);
dao 是一个包含(除其他外)几个嵌入文档的猫鼬表示。作为测试,我在调用上面的更新方法之前从数组中删除了几个嵌入式文档。
结果是对嵌入式文档数组的更改未保留。
我忽略了什么?
【问题讨论】:
如果没有看到更多代码,很难确定,但如果 dao 是 Mongoose 模型实例,您应该调用 dao.save(cb);。
【讨论】:
MongoError: E11000 duplicate key error index。这就是我选择我所描述的原因。也许有一个dao.save 选项可以在我不知道的重复键的情况下覆盖?
new 导致了问题?
我通过执行以下问题中提出的类似操作解决了这个问题:https://github.com/LearnBoost/mongoose/issues/571
为了完整起见,一些导致问题的背景。
我正在使用在应用程序启动时填充的 DDD 存储库。在后台,这会获取 Mongoose 对象(在我的情况下被视为 DAO)并被转换为缓存在存储库中的域对象。我需要域对象和猫鼬对象之间的这种分离,不要问。
这意味着getById、getAll 和 repo 的所有其他公共接口都使用域对象而不是猫鼬对象。
当在 repo 上执行 add 或 update 之类的操作时,这只会在内部更新 in-mem 缓存(同样,它仅使用域对象而不是 mongoose 对象)
只有在 repo 上执行 commit 时,可能更改的域对象集合才会被持久化。这是通过创建新的猫鼬对象而不是获取现有的猫鼬对象并更新它们来完成的。
这就是为什么我不能使用dao.save() 的原因,因为当我保存不同的(刚刚创建的)猫鼬对象而具有相同 id 的猫鼬对象可能已经存在于 Mongo 中时,它会引发重复身份证错误。
一些相关的sn-p来自说明解决方案的代码:
var dao = that.createDAO(domainobject);
//https://github.com/LearnBoost/mongoose/issues/571 // Convert the Model instance to a simple object using Model's 'toObject' function // to prevent weirdness like infinite looping... var upsertData = dao.toObject(); // Delete the _id property, otherwise Mongo will return a "Mod on _id not allowed" error delete upsertData._id; that.model.update({_id: dao._id}, upsertData, { upsert: true }, cb);
【讨论】: