我正在尝试在Mongoose中定义一个文件夹架构。对于每个文件夹,我想存储对父文件夹以及子子文件夹数组的引用(以使在任一方向的遍历都变得容易):
var folderSchema = new mongoose.Schema({
name: String,
parent: { type: Schema.Types.ObjectId, ref: 'Folder' },
subfolders: [{ type: Schema.Types.ObjectId, ref: 'Folder' }],
});
Run Code Online (Sandbox Code Playgroud)
创建文件夹时,我只希望指定父文件夹,然后使用预先保存的钩子将子文件夹添加到父文件夹的subfolders数组中。这部分工作正常:
folderSchema.pre('save', function (next) {
var self = this;
// If creating a subfolder, then add the subfolder to
// the parent folder's "subfolders" array
if (this.parent) {
Folder.findById(this.parent, function (err, parent) {
if (err) return next(err);
if (parent) {
parent.subfolders.push(self);
return parent.save(next);
}
return next();
});
} else {
next();
}
});
Run Code Online (Sandbox Code Playgroud)
另外,在删除子文件夹时,我想使用预删除钩子自动从父文件夹的subfolders数组中删除子文件夹。不幸的是,我无法使这部分工作:
folderSchema.pre('remove', function (next) {
var self = this;
// If deleting a subfolder, then remove it from the parent
// folder's "subfolders" array
//
// (Note: it would also be a good idea to recursively remove
// all subfolders here, but I'm not attempting this yet.)
if (this.parent) {
Folder.findById(this.parent, function (err, parent) {
if (err) return next(err);
if (parent) {
parent.subfolders.id(self._id).remove(); // TypeError: Object 53a64349741d1ae82274c9a2 has no method 'id'
return parent.save(next);
}
return next();
});
} else {
next();
}
});
Run Code Online (Sandbox Code Playgroud)
错误的这一行是这一行:
parent.subfolders.id(self._id).remove();
Run Code Online (Sandbox Code Playgroud)
它导致此错误:
TypeError: Object 53a64349741d1ae82274c9a2 has no method 'id'
at Promise.<anonymous> (C:\Users\serg\temp\mongoose\folders\index.js:53:35)
at Promise.<anonymous> (C:\Users\serg\temp\mongoose\folders\node_modules\mongoose\node_modules\mpromise\lib\promise.js:177:8)
at Promise.EventEmitter.emit (events.js:95:17)
at Promise.emit (C:\Users\serg\temp\mongoose\folders\node_modules\mongoose\node_modules\mpromise\lib\promise.js:84:38)
at Promise.fulfill (C:\Users\serg\temp\mongoose\folders\node_modules\mongoose\node_modules\mpromise\lib\promise.js:97:20)
at C:\Users\serg\temp\mongoose\folders\node_modules\mongoose\lib\query.js:1393:13
at model.Document.init (C:\Users\serg\temp\mongoose\folders\node_modules\mongoose\lib\document.js:250:11)
at completeOne (C:\Users\serg\temp\mongoose\folders\node_modules\mongoose\lib\query.js:1391:10)
at Object.cb (C:\Users\serg\temp\mongoose\folders\node_modules\mongoose\lib\query.js:1150:11)
at Object._onImmediate (C:\Users\serg\temp\mongoose\folders\node_modules\mongoose\node_modules\mquery\lib\utils.js:137:16)
Run Code Online (Sandbox Code Playgroud)
我试图做的是使用该MongooseDocumentArray#id方法删除子文档,如Mongoose文档的“ 子文档”页面上的示例所示。但是,该方法似乎不可用,我不确定为什么会这样。我定义的模式不正确吗?该id方法在中间件中不可用吗?还是我只是使用不正确?
此处的区别在于您使用的是对数组中对象的嵌入式引用,而不是直接的子文档。在子文档的猫鼬示例中,它显示:
var childSchema = new Schema({ name: 'string' });
var parentSchema = new Schema({
children: [childSchema]
});
Run Code Online (Sandbox Code Playgroud)
因此,在此示例中,每个“子”实际上直接存储在“父”中(因此子生活在父集合中)。在您的方案中,您引用的是subfoldersID,而不是对象的直接存储:
subfolders: [{ type: Schema.Types.ObjectId, ref: 'Folder' }],
Run Code Online (Sandbox Code Playgroud)
因此,当您执行查询时,结果subfolders实际上是ID数组,其中一个是53a64349741d1ae82274c9a2。这没有id导致您的问题的方法。但是,您可以使用populate这些ID填充对象。但是即使那样做也不能满足您的DocumentArray需要,因为猫鼬将其简单地视为Array,而不是DocumentArray(将具有id您要查找的功能)。 您可以在此处看到用于确定如何投射这些对象的逻辑。最后,您会看到当加载这些对象时,猫鼬会将它们转换为一种Array类型:
return new Types.Array(path, cast || Types.Mixed, obj);
Run Code Online (Sandbox Code Playgroud)
因此,如果您想使用此id功能,则可以更改架构,也可以直接执行其功能。 逻辑不是那么多,因此您可以考虑只在阵列中搜索手动匹配该ID的那个。
| 归档时间: |
|
| 查看次数: |
3722 次 |
| 最近记录: |