猫鼬:如何在不填充一级田地的情况下填充 2 级深度种群?在蒙戈德布



这是我的猫鼬模式:

var SchemaA = new Schema({
    field1: String,
 .......
 fieldB : { type: Schema.Types.ObjectId, ref: 'SchemaB' }
});
var SchemaB = new Schema({
    field1: String,
 .......
 fieldC : { type: Schema.Types.ObjectId, ref: 'SchemaC' }
});
var SchemaC = new Schema({
    field1: String,
 .......
 .......
 .......
});

当我使用查找查询访问架构 A 时,我想拥有字段/属性模式 A 以及模式 B 和架构 C,就像我们在 SQL 数据库中应用连接操作一样。

这是我的方法:

SchemaA.find({})
 .populate('fieldB')
 .exec(function (err, result){ 
       SchemaB.populate(result.fieldC,{path:'fieldB'},function(err, result){
    .............................
        });
}); 

上面的代码运行良好,但问题是:

  1. 我想通过架构 A 获得 SchemaC 的信息/属性/字段,并且我不想填充 SchemaB 的字段/属性。
  2. 不想获取 SchemaB 属性的原因是,额外的填充将减慢不必要的查询速度。

长话短说:我想通过架构 A 填充架构 C,而不填充架构 B。

你能建议任何方式/方法吗?

作为一个狂热的mongodb粉丝,我建议你使用关系数据库来处理高度关系的数据 - 这就是它的目的。 当您必须执行 3+ 查询以获取单个对象时,您将失去 mongodb 的所有好处。

Buuuuuut,我知道这个评论会被置若罔闻。 你最好的选择是尽可能有意识地关注表现。第一步是将字段限制为所需的最小值。 即使使用基本查询和任何数据库引擎,这也是很好的做法 - 仅获取所需的字段(例如。 SELECT * FROM === 不好...别再做了! 您还可以尝试执行精益查询,以帮助节省猫鼬对数据所做的大量后处理工作。 我没有测试这个,但它应该可以工作...

SchemaA.find({}, 'field1 fieldB', { lean: true })
.populate({
    name: 'fieldB',
    select: 'fieldC',
    options: { lean: true }
}).exec(function (err, result) {
    // not sure how you are populating "result" in your example, as it should be an array, 
    // but you said your code works... so I'll let you figure out what goes here.
});

此外,一种非常"mongo"的方法来执行您想要的操作,方法是将 SchemaC 中的引用保存回 SchemaA。 当我说"mongo"的方式时,你必须摆脱你多年来对关系数据查询的思考。 尽一切努力对数据库执行更少的查询,即使它需要双向引用和/或数据重复。

例如,如果我有一个书籍架构和作者

架构,我可能会将作者的名字和姓氏保存在"书籍"集合中,以及"作者"集合中对完整配置文件的_id引用。 这样,我可以在单个查询中加载我的书籍,仍然显示作者的姓名,然后生成指向作者个人资料的超链接:/author/{_id} .这被称为"数据非规范化",众所周知,它会给人们带来胃灼热。我尝试将其用于不经常更改的数据 - 例如人们的名字。在名称确实更改的情况下,编写一个函数来更新多个位置的所有名称是微不足道的。

 SchemaA.find({})
 .populate({
  path: "fieldB",
  populate:{path:"fieldC"}
  }).exec(function (err, result) {
     //this is how you can get all key value pair of SchemaA, SchemaB and SchemaC
     //example: result.fieldB.fieldC._id(key of SchemaC)
  });

为什么不添加一个ref SchemaC SchemaA? 如果没有像您当前拥有它的方式SchemaB,则无法从SchemaA桥接到SchemaC,除非您填充SchemaB除了要SchemaC ref之外没有其他数据

"字段选择"下的文档中所述,您可以限制返回的字段。 .populate('fieldB')变得populate('fieldB', 'fieldC -_id').-_id 需要省略_id字段,就像使用 select() 一样。

我认为这是不可能的。因为,当 A 中的文档引用 B 中的文档并且该文档引用 C 中的另一个文档时,A 中的文档如何在没有 B 帮助的情况下知道要从 C 引用哪个文档。

最新更新