猫鼬填充对子文档的引用

Posted

技术标签:

【中文标题】猫鼬填充对子文档的引用【英文标题】:mongoose populate reference to subdocument 【发布时间】:2015-07-28 14:08:09 【问题描述】:

我找不到对我的问题的任何回应。可能也是一个搜索问题,但希望能得到一些帮助。 我有以下型号:

var ChildSchema =  new Schema (
    'name': string
);
var ClassSchema =  new Schema (
    'name': string, 
    'children': [ChildSchema] 
);

我只为类声明了一个模型。

mongoose.model ('Class', ClassSchema); 

然后我有另一个模型:

var TeacherSchema = new Schema (
   'name': string, 
   'favorite': type: ObjectId, ref: 'Class.children' // a child from class children
   'least': type: ObjectId, ref: 'Class.children' // same as above
); 

有相关型号:

mongoose.model ('Teacher', TeacherSchema); 

我正在尝试通过 ID 检索老师并填充孩子的姓名:

Teacher.findbyId (teacherId).populate (favorite least)... 

这似乎不起作用。这个建模正确吗?这可能吗?

(我知道我的例子在政治上可能不正确,所以请原谅我......)

编辑 这是项目中某些东西的反映。我知道可以将孩子建模为单独的集合,但在我的项目中,我更喜欢将它们保留为嵌入式文档(出于各种原因)。 当推入 children 数组并保存类时,每个孩子都会得到一个 _id。老师需要在“最喜欢”和“最不喜欢”的班级中指向一个孩子,即保留那个孩子的_id。

【问题讨论】:

我可以看到问题是我也需要传递classId,只是不确定如何。 我认为您需要的是简单地从ChildSchema 创建一个模型,然后直接引用它。 好的,首先我想在这一点上我首先应该提出 Mongoose 的模式和模型与 MonogoDB 的集合之间的区别.除非你已经知道,Mongoose 的模式和模型只是更高级别的包装器,否则 MongoDB 所做的只是将文档存储在集合中。因此,回到您的情况,ChildSchema 或 Mongoose 中的相关模型最终都会在 MongoDB 中创建一个集合“孩子”,其中将包含各种文档。如果您想将它们区分为 Family 子项或 Class 子项,则需要存储一个标志。 我明白了。它没有任何改变。嵌入式文档(语法:children: [childSchema])在两个方面与引用(可填充)文档(语法:ref: 'Children')本质上不同:(1.)嵌入式文档实际上不需要填充,它们已经主文档的 part (在 MongoDB 级别下)。 (2.) 引用(可填充)文档存储为它们自己的文档(集合),因此它们是实际需要 填充的文档。简而言之:您无法填充嵌入式文档。 PS:除非你提到我@laggingreflex,否则我不会收到通知 @laggingreflex 似乎已经结束了。 github.com/Automattic/mongoose/issues/2772 【参考方案1】:

答案似乎是:不可行。 github.com/Automattic/mongoose/issues/2772 另外 - 找不到合适的插件。

【讨论】:

我找到了某种使用虚拟属性的可行解决方案 - 请参阅上面的答案【参考方案2】:

我也有类似的问题。至少如果您从 Child 引用回 Class,这可能会起作用:

var TeacherSchema = new Schema (
   'class': type: ObjectId, ref: 'Class'
   'name': string, 
   '_favorite': type: ObjectId, ref: 'Class.children' // a child from class children
   '_least': type: ObjectId, ref: 'Class.children' // same as above
); 


TeacherSchema.virtual('favorite').get(function() 
  return this.class.children.id(this._favorite);
);
TeacherSchema.virtual('favorite').set(function(favorite) 
  this._favorite = favorite;
);

TeacherSchema.virtual('least').get(function() 
  return this.class.children.id(this._least);
);
TeacherSchema.virtual('least').set(function(least) 
  this._least = least;
);

TeacherSchema.set('toJSON',  getters: true, virtuals: true );

只要老师只有 1 个班级,此方法就有效。

【讨论】:

以上是关于猫鼬填充对子文档的引用的主要内容,如果未能解决你的问题,请参考以下文章

如何通过填充字段在猫鼬中查找文档?

如何通过填充字段在猫鼬中查找文档?

猫鼬模式参考和填充

无法在 NestJS 应用程序中启动并运行猫鼬虚拟填充

单元测试:使用填充时如何模拟猫鼬代码?

猫鼬填充没有引用的 ObjectId 的通用数组