是否可以在 mongoosejs 模式中填充自引用?

Posted

技术标签:

【中文标题】是否可以在 mongoosejs 模式中填充自引用?【英文标题】:Is it possible to populate a self reference in a mongoosejs schema? 【发布时间】:2013-04-08 09:06:52 【问题描述】:

我有一个猫鼬模型模式,我正在尝试为一些预先存在的 mongodb 文档构建它。现有的 mongo 文档具有对同一集合的自引用。我试图创建一个表示这种关系的模式,然后尝试使用populate method。架构如下所示(为简洁起见,删除了一些属性):

var fileSchema = new Schema(
    _id:  type: String ,
    pcap: 
        files: [ type: Schema.Types.ObjectId, ref: 'Files' ]
    
);

var file = artifactConn.model('Files', fileSchema, 'info');

然后我使用上面的模型进行查询,然后像这样填充:

models.file.findById("91320684-9a1a-4f2a-a03f-63a7a208ec9b")
.populate('pcap.files') // have also tried just 'files' w/ the same result
.exec(function (err, file) 
    if (!err) 
        console.log(file);
     else 
        console.log(err);
    
);

导致这个

 _id: '91320684-9a1a-4f2a-a03f-63a7a208ec9b',
  pcap: 
    files: [] 

如果我在 mongohub 中检查我的文档,它看起来像这样

 "_id" : "91320684-9a1a-4f2a-a03f-63a7a208ec9b",
  "pcap" : 
    "files" : [ 
       "_id" : "e4eed129-b4aa-46fc-8df2-3f3f92e6fe53" , 
       "_id" : "8c0ecb98-452e-475d-a521-feba5c3d1426" , 
       "_id" : "4b87c467-f396-4bcf-a7b0-8419e8441ec0"  ]  

我的填充调用是否有问题?这是我设置架构的方式吗?是数据的存储方式吗?

【问题讨论】:

【参考方案1】:

您的架构不正确。您拥有的架构将匹配这样的集合:

 "_id" : "91320684-9a1a-4f2a-a03f-63a7a208ec9b",
  "pcap" : 
    "files" : [ 
       ObjectId("e4eed129-b4aa-46fc-8df2-3f3f92e6fe53") , 
       ObjectId("8c0ecb98-452e-475d-a521-feba5c3d1426") , 
       ObjectId("4b87c467-f396-4bcf-a7b0-8419e8441ec0")  ]  

架构应该是:

var fileSchema = new Schema(
    _id:  type: String ,
    pcap: 
        files: [ 
            _id:  type: String, ref: 'Files' 
        ]
     );

应该可以的。

【讨论】:

它不再是一个空集,而是现在改为files: [ undefined, undefined, undefined ]。它至少现在正在阅读参考资料,但没有填充它们。还有其他想法吗? 您还需要将填充调用更新为:populate('pcap.files._id') 不幸的是.populate('files').populate('pcap.files._id'),有同样的影响,我仍然以files: [ undefined, undefined, undefined ]告终。但是,.populate('pcap.files') 会引发错误TypeError: Cannot read property 'ref' of undefined。关于我缺少什么的任何想法? 所以你基本上是正确的。我只需要稍微调整您的答案以使用 String 而不是 ObjectId。谢谢!【参考方案2】:

架构看起来不错。以相同的方式存储数据,你应该很好:例如

 "_id" : "91320684-9a1a-4f2a-a03f63a7a208ec9b",
  "pcap" : 
  "files" : [ ObjectId("e4eed129-b4aa-46fc-8df2-3f3f92e6fe53"), ObjectId("8c0ecb98-452e-475d-a521-feba5c3d1426"), ObjectId("4b87c467-f396-4bcf-a7b0-8419e8441ec0")] 
   

然后

Model.find(..).populate('pcap.files').exec(..)

【讨论】:

以上是关于是否可以在 mongoosejs 模式中填充自引用?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 mongoosejs 中深度填充多个路径?

MongooseJS 在填充后返回空数组

无法使用 mongoosejs 填充

Mongoose JS - 填充方法不返回完整引用的对象... - 仅返回 objectId 版本

MongooseJS 使用多个目标字段填充

Mongoose 填充排序选项