如何通过条件匹配子文档中的数组元素

我有以下Mongoose模式:

EmployeeSchema:

var EmployeeSchema = new Schema({ name : String, employeeDetailsId: { type: Schema.Types.ObjectId, ref: 'employeedetails' } }); 

EmployeeDetailSchema:

 var EmployeeDetailSchema = new Schema({ employeeId: { type: Schema.Types.ObjectId, ref: 'employee' }, primarySkills: [ { type: Schema.Types.ObjectId, ref: 'skills' } ], }); 

SkillsSchema:

 var SkillsSchema = new Schema({ name: { type: String, required: true } }); 

EmployeeDetailSchema数据被按需保存,就像特定的技能被分配给Employee一样。 一旦保存了EmployeeDetail文档,相应的EmployeeDetailID将以EmployeeDetailIDforms保存回EmployeeSchema

现在EmployeeSchemaEmployeeDetailSchema之间有双向关系。

注:多个技能可以关联到一个员工,他们存储在EmployeeDetails架构中ObjectID的数组。

UseCase:

我想获取所有具有特定技能的员工,技能将被input到Mongoose / Mongo查询中。

说input技能ID是1234,然后我想要获取EmployeeDetail> PrimarySkills数组中具有Skill id 1234的所有员工。

以下是我尝试使用mongoose的方法:

 EmployeeModel.aggregate([ { $lookup: { from: 'employeedetails', localField: 'employeeDetailsId', foreignField: '_id', as: 'details' } }, { $match: { $and: [ { "details.primarySkills": { "$exists": true } }, { "details.primarySkills": { $in: [mongoose.Types.ObjectId(req.params.skillId)] } } ] } } ]).exec(function (err, result) { if (err) return res.send('400', { message: 'Unable to fetch employees data by status. Please try again later' }); return res.jsonp(result); }); 

结果 :空arrays。

我不知道哪里出错,需要一些帮助。

我遵循的原始方法很糟糕,除了一个小小的错误之外。 我应该使用req.query.skillId而不是req.params.skillId

对于那些想知道不同的b / w查询和参数,请检查这个答案

这是最终的解决scheme,认为它可以帮助其他人:

 EmployeeModel.aggregate([ { $lookup: { from: 'employeedetails', localField: 'employeeDetailsId', foreignField: '_id', as: 'details' } }, { $match: { $and: [ { "details.primarySkills": { "$exists": true } }, { "details.primarySkills": { $in: [mongoose.Types.ObjectId(req.query.skillId)] } } ] } } ]).exec(function (err, result) { if (err) return res.send('400', { message: 'Unable to fetch employees data by status. Please try again later' }); return res.jsonp(result); }); 

您可以采取的一种方法是先将$lookup应用于EmployeeDetails模型的Skills模型,然后再对Employee模型进行查找

 EmployeeDetails.aggregate([ { "$match": { "primarySkills": req.query.skillId } }, { "$unwind": "$primarySkills" }, // skip this pipeline step for MongoDB 3.4 and above { "$lookup": { "from": "skills",// ensure this is the correct collection name "foreignField": "_id", "localField": "primarySkills", "as": "skills" } }, { "$unwind": "$skills" } { "$group": { "_id": "$_id", "employeeId": { "$first": "$employeeId" }, "primarySkills": { "$push": "$skills" } } }, { "$lookup": { "from": "employees",// ensure this is the correct collection name "foreignField": "_id", "localField": "employeeId", "as": "employee" } } ]).exec(callback);