我有以下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
将保存回EmployeeSchema
employeeDetailsId
。
现在EmployeeSchema
和EmployeeDetailSchema
之间存在双向关系。
注意: 多个技能可以与Employee关联,并且它们作为ObjectID的数组存储在EmployeeDetails Schema中。
UseCase:
我想获取所有具有与之关联的特定技能的员工,技能将输入到Mongoose / Mongo查询。
说输入技能ID是1234然后我想要获取在EmployeeDetail中具有技能ID 1234的所有员工> PrimarySkills数组。
以下是我尝试使用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);
});
结果:空数组。
我不知道哪里出错了,需要一些帮助。
答案 0 :(得分:1)
我所遵循的糟糕的原创方法除了一个小错误外都很好。我应该使用req.query.skillId
代替req.params.skillId
对于那些想知道不同的b / w查询和参数的人,请查看answer
这是最终解决方案,认为它可以帮助其他人:
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);
});
答案 1 :(得分:0)
您可以采取的一种方法是先将$lookup
应用于Skills
模型上的EmployeeDetails
模型,然后再对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);