Node.js Mongoose根据模型引用模型的字段对模型进行嵌套查询

Node.js Mongoose根据模型引用模型的字段对模型进行嵌套查询,node.js,mongodb,mongoose,populate,Node.js,Mongodb,Mongoose,Populate,关于stackoverflow这个话题,似乎有很多问答,但我似乎在任何地方都找不到确切的答案 我所拥有的: Company.find({'founder.id': 'Robertson'}, function(err, companies){ console.log(companies); // getting an empty array }); 我有公司和个人模型: var mongoose = require('mongoose'); var PersonSchema = new

关于stackoverflow这个话题,似乎有很多问答,但我似乎在任何地方都找不到确切的答案

我所拥有的:

Company.find({'founder.id': 'Robertson'}, function(err, companies){
    console.log(companies); // getting an empty array
});
我有公司和个人模型:

var mongoose = require('mongoose');
var PersonSchema = new mongoose.Schema{
                        name: String, 
                        lastname: String};

// company has a reference to Person
var CompanySchema = new mongoose.Schema{
                        name: String, 
                        founder: {type:Schema.ObjectId, ref:Person}};
我需要什么:

Company.find({'founder.id': 'Robertson'}, function(err, companies){
    console.log(companies); // getting an empty array
});
查找姓“罗伯逊”的人创办的所有公司

我的尝试:

Company.find({'founder.id': 'Robertson'}, function(err, companies){
    console.log(companies); // getting an empty array
});
然后我发现这个人不是嵌入的,而是被引用的,所以我使用“填充”来填充创始人人,然后尝试使用find和“Robertson”姓

// 1. retrieve all companies
// 2. populate their founders
// 3. find 'Robertson' lastname in populated Companies
Company.find({}).populate('founder')
       .find({'founder.lastname': 'Robertson'})
       .exec(function(err, companies) {
        console.log(companies); // getting an empty array again
    });
我仍然可以用个人id作为字符串查询公司。但这并不是你能理解的我想要的

Company.find({'founder': '525cf76f919dc8010f00000d'}, function(err, companies){
    console.log(companies); // this works
});

因为MongoDB不支持连接,所以不能在单个查询中执行此操作。相反,您必须将其分为两个步骤:

//获取姓罗伯逊的人的_id。
find({lastname:'Robertson'},{u id:1},函数(err,docs){
//将文档映射到仅包含_id的数组中
var id=docs.map(函数(doc){return doc.\u id;});
//找那些创始人在这一组的公司。
查找({founder:{$in:ids}}),函数(err,docs){
//文档包含您的答案
});
});

如果最近有人遇到这种情况,Mongoose现在支持类似连接的功能,并具有一个名为“填充”的功能

从Mongoose文档中:

Story.findOne({ 
    title: 'Casino Royale' 
}).populate('author').exec(function (err, story) {
    if (err) return handleError(err);
    console.log('The author is %s', story.author.name);
    // prints "The author is Ian Fleming"
});

我做这件事已经很晚了:p但我只是在寻找一个类似的答案,我想我会分享我的想法,以防有人出于同样的原因发现这件事

我找不到通过mongoose查询实现这一点的方法,但我认为使用

要获取您要查找的查询,可以执行以下操作:

const result=wait Company.aggregate([
{$lookup:{
从:"人",,
localField:“创始人”,
foreignField:“\u id”,
as:'创始人'}
},
{$unwind:{路径:'$FOUNTER'}},
{$match:{'founder.lastname':'Robertson'}
]);
行为类似于
.populate()
,用实际数据替换引用。但它返回一个数组,因为它可以用于匹配多个文档

从数组中删除项,在这种情况下,只需将单个元素数组转换为字段

然后执行听起来像的操作,只返回与查询匹配的文档。如果需要,还可以执行比严格相等更复杂的匹配

一般来说,聚合管道的工作方式是在每一步中不断过滤/修改匹配的文档,直到得到您想要的

我还没有检查这方面的性能,但我肯定更喜欢让Mongo来做这项工作,而不是过滤掉服务器端不必要的结果


我想唯一的缺点是结果将只是一个对象数组,而不是mongoose模型,因为管道通常会改变文档的形状。因此,您将无法对返回的数据使用模型的方法。

您是对的,这看起来确实像一个关节。我给出了我正在考虑实现的最简单的嵌套查询,这可能是关系数据库更方便的情况。但不管怎样,你的解决方案奏效了。Thnx!您好,我一直在寻找这个答案,因为我有同样的问题,但最后一个问题,这是否已经改变,或者是否可能在猫鼬3.8.5现在?我意识到,自从这个问题发布后,mongoose升级了几个版本。@maumercado不,它没有改变,也不太可能。是否有任何更新,或者我仍然需要使用此解决方法?这非常有帮助!谢谢你的清晰解释。如果你要做的是
findMany({})
,而有多个作者
authors[{type:Schema.ObjectId,ref:'author'}]
,你会怎么做并访问作者的名字?他要求查询嵌套的ref而不是填充,他想按作者的名字查找故事