Mongoose:如何通过子集合的文档属性值查找文档

时间:2017-01-15 04:16:36

标签: node.js mongodb mongoose

我正在使用Mongoose版本4.6.8和MongoLab(MLab)。我有一个名为“Group”的Mongoose模式,它有一个名为“teachers”的用户子文档集合:

var GroupSchema = new Schema({
//…more properties here…//
teachers: [{
            type: Schema.ObjectId,
            ref: 'User'
        }]
});

这是来自MongoLab上“groups”集合的文档:

{
//…more properties here…//
    "teachers": [
        {
            "$oid": "5799a9c759feea9c208c004c"
        }
    ]
}

这是来自MongoLab上“users”集合的文档:

{
//…more properties here…//
    "username": "bob"
}

但是,如果我想获得一个具有特定教师(用户)且用户名为“bob”的群组列表,则这不起作用(群组列表为空):

Group.find({"teachers.username": "bob"}).exec(callback);

这也不会返回任何项目:

Group.find().where('teachers.username').equals('bob').exec(callback);

我怎样才能做到这一点?

3 个答案:

答案 0 :(得分:1)

你可以使用populate来做到这一点。

试试这个:

populate

populateteachers基于path字段(给定match)和username将仅返回mongoose populate options bob的人。

有关{{1}}的详情,请参阅Mongoose populate documentation

答案 1 :(得分:1)

如果没有更多关于你的设置的知识(特别是你是否想要任何一个名叫鲍勃的人或一个你可以先拿起你的id的特定Bob) - 这可能会有所帮助,尽管我认为这需要你将你的教师阵列弄平只是他们的ID,而不是单键对象。

User.findById(<Id of Bob>, function(err, user){
    Group.find({}, function(err, groups){
      var t = groups.map(function(g){
        if(g['teachers'].indexOf(user.id))
          return g
      })
    // Do something with t
    })
})

答案 2 :(得分:0)

我认为这种情况下的解决方案是通过用户模块获取教师组,而不是通过组模块的第一次倾向。这是有道理的,因为它符合现代API如何表示一对多关系。

例如,在Behance的API中,用户项目的端点是:

GET /v2/users/user/projects

对此端点的请求(用户的用户名为“matiascorea”)将如下所示:

https://api.behance.net/v2/users/matiascorea/projects?client_id=1234567890

所以在我的情况下,我不需要通过老师找到小组,而是需要通过用户名找到用户(老师),填充老师的小组,然后使用它们:

User.findOne({username: 'bob'})
     .populate('groups')
      .exec(callback);

对此的API调用将是:

GET /api/users/user/groups

对此端点的请求如下所示:

https://example.com/api/users/bob/groups