Mongoose 不会更新子文档
Posted
技术标签:
【中文标题】Mongoose 不会更新子文档【英文标题】:Mongoose won't update sub-document 【发布时间】:2015-07-12 05:31:00 【问题描述】:我已经为此苦苦思索了几个小时,但似乎无法弄清楚。我决定在一个学习项目中使用 Mongo,看看我有多喜欢它。 Mongoose 是推荐的使用方式,所以我也深入研究了它。我有两个架构:
var PluginSchema = new Schema(
name: type: String, required: true ,
slug: type: String ,
description: type: String ,
created_date: type: Date, default: Date.now ,
active: type: Boolean, default: true ,
user: type: Schema.Types.ObjectId, ref: 'User' ,
versions: [PluginVersion.schema]
);
PluginSchema.methods.getLatestVersion = function(callback)
if(this.versions.length > 0)
this.versions.sort(function(a, b)
if(semver.gt(a.version, b.version))
return 1;
else if(semver.lt(a.version, b.version))
return -1;
else
return 0;
);
callback(this.versions[this.versions.length-1]);
else
callback(undefined);
;
和
var PluginVersionSchema = new Schema(
version: type: String, required: true ,
downloads: type: Number, default: 0 ,
size: type: Number, required: true ,
updatedChecks: type: Number, default: 0 ,
fileName: type: String, required: true ,
uploadedDate: type: Date, default: Date.now
);
这里的问题是“版本”关系。在某个时候,我想更新插件的一个版本。我要更新的是updatedChecks
字段。基本上只是updatedChecks += 1
。
Plugin.findById(req.params.plugin_id)
.populate('user')
.populate('versions')
.exec(function(err, plugin)
if(err)
res.status(404);
res.send("Plugin not found.");
else
plugin.getLatestVersion(function(version)
if(version !== undefined)
pluginData =
stuff: "that",
gets: "returned",
tothe: "user"
;
// This says 'Affected: 1'. As expected
PluginVersion.update(_id: version._id,
updatedChecks: version.updatedChecks + 1
, function(err, affected)
console.log("Affected: " + affected);
if(err) res.send(err);
res.status(200);
res.json(pluginData);
);
else
res.status(404);
res.send("No versions found for this plugin.");
);
);
到目前为止,一切都很好。但是,当我尝试通过插件模式再次访问该版本时,updatedChecks
值没有改变!我检查了我正在更新的版本上的_id
值与从Plugin.versions
字段中提取的版本,它们是相同的。我是否需要从Plugin.versions
中删除版本并重新插入具有更新值的新版本?我也尝试更新值并调用save()
,但这似乎也不起作用。
【问题讨论】:
作为另一个提示,这对 SQLy 来说有点像我的口味。如果您在其他模式之间共享 PluginVersion,它可能在一个单独的模块中,但即使在这种情况下,它也不应该是一个单独的集合。然后更新也更容易。否则,如果 MongoDB 优于 SQL,您将失去一个。 【参考方案1】:我最终通过直接从插件对象访问插件版本来完成这项工作。
var pluginIndex = false;
for(var i = 0; i < plugin.versions.length; i++)
if(plugin.versions[i]._id === version._id)
pluginIndex = i;
if(pluginIndex !== false)
plugin.versions[pluginIndex].updatedChecks++;
plugin.versions[pluginIndex].markModified('updatedChecks');
plugin.versions[pluginIndex].save(function()
plugin.markModified('versions');
plugin.save(function()
res.status(200);
res.json(pluginData);
);
);
我也得到了一点帮助:Mongoose save() not updating value in an array in database document
【讨论】:
【参考方案2】:这里的问题是,您的更新查询写错了。应该是
PluginVersion.update(
_id: version._id
,
$set:
updatedChecks: version.updatedChecks + 1
, function(...)
...
);
或
PluginVersion.update(
_id: version._id
,
$inc:
updatedChecks: 1
, function(...)
...
);
您可以在此处找到更多更新运算符: http://docs.mongodb.org/manual/reference/operator/update/
【讨论】:
以上是关于Mongoose 不会更新子文档的主要内容,如果未能解决你的问题,请参考以下文章
Mongoose - 使用 findOneAndUpdate 更新子文档
更新子文档、NodeJS 和 Mongoose 的更有效方式