我使用Nodejs,Hapijs和Mongoose .
我的架构和模型如下 .
var schema = {
name: {
type: String,
required: true
},
lectures: {}
};
var mongooseSchema = new mongoose.Schema(schema, {
collection: "Users"
});
mongoose.model("Users", mongooseSchema);
出于某种原因,我需要将“讲座”作为混合类型 .
在保存/创建文档时,我创建了一个嵌套属性 lectures.physics.topic[] ,其中topic是一个数组 .
现在,我正在尝试使用$ addToSet或$ push将新对象添加/推送到“lectures.physics.topic” .
userModel.findByIdAndUpdateAsync(user._id, {
$addToSet: {
"lectures.physics.topic": {
"name": "Fluid Mechanics",
"day": "Monday",
"faculty": "Nancy Wagner"
}
}
});
但该文件根本没有得到更新 . 我也试过使用$ push . 没有任何效果 . 可能是什么问题呢?
我试图使用mongoclient的另一种方法,直接更新数据库 . 它的工作原理请找到下面的代码
db.collection("Users").update({
"_id": user._id
}, {
$addToSet: {
"lectures.physics.topic": {
"name": "Fluid Mechanics",
"day": "Monday",
"faculty": "Nancy Wagner"
}
}
}, function(err, result) {
if (err) {
console.log("Superman!");
console.log(err);
return;
}
console.log(result);
});
每次请求被命中时我都必须启动mongo客户端 . 这不是一个可行的解决方案 .
2 回答
我会打电话给"bug" . Mongoose显然做了错误的事情,如后面所示的日志记录中可以证明的那样 . 但是这里有一个列表,它使用您尝试执行的相同更新从本机驱动程序调用
.findOneAndUpdate()
:这与结果完美配合:
你需要小心,因为本机驱动程序方法不像mongoose方法那样知道连接状态 . 因此,您需要确保通过先前触发的“mongoose”方法 Build 连接,或者将您的应用程序包装在连接事件中,如下所示:
至于“bug”,请查看此列表的日志记录输出:
并且使用mongoose日志记录的记录输出:
所以在真正的"What the Fudge?"风格中,有一个叫
.findOne()
的电话?这不是问的问题 . 此外,当然数据库中没有任何改变,因为进行了错误的调用 . 所以即使这里的{ "new": true }
也是多余的 .这种情况发生在具有“混合”模式类型的所有级别 .
就个人而言,我不会像这样嵌套在“对象”中,只需将“对象键”作为标准数组的一部分作为附加属性 . MongoDB和mongoose都对此更加满意,并且查询具有这种结构的信息要容易得多 .
输出:
这样工作正常,你不需要挖掘原生方法只是为了让它工作 .
数组的属性使查询和过滤非常容易,以及跨数据的“聚合”信息,对于所有这些信息,MongoDB都喜欢引用所有信息的“严格路径” . 否则,您只是“特定键”,并且在不提及每个可能的“键组合”的情况下,无法对其进行索引或搜索 .
像这样的属性是一个更好的方法 . 这里没有错误 .
Mongoose失去了自动检测并保存对Mixed类型所做更改的功能,因此您需要通过调用文档的 .markModified(path) 方法来更改混合类型的值,该方法将路径传递给您刚刚更改的Mixed类型:
在您的情况下,您可以使用 findById() 方法通过调用主题数组上的 addToSet() 方法进行更改,然后触发 save() 方法来保留更改: