以下是两个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'
},
statusId: {
type: Schema.Types.ObjectId,
ref: 'status'
}
});
EmployeeDetailSchema数据按需保存,例如将特定状态分配给Employee时。在这种情况下,一旦保存了EmployeeDetail文档,则相应的EmployeeDetailID将作为 employeeDetailsId
保存回EmployeeSchema。现在EmployeeSchema和EmployeeDetailSchema之间存在双向关系。
UseCase:
我想获取所有标记为特定状态的员工。假设输入状态ID为1234
,那么我想在EmployeeDetail文档中获取状态ID为1234
的所有员工。
以下是我尝试使用Mongoose的方法:
exports.getEmployeesByStatus = function (req, res) {
console.log('Status ID : ' + req.query.statusId);
EmployeeModel.find({'employeeDetailsId.statusId': {$eq: mongoose.Types.ObjectId(req.params.statusId)}})
.exec(function (err, result) {
if (err)res.send('400', {message: 'Unable to fetch employees data by status. Please try again later'});
res.jsonp(result);
});
};
虽然有员工被分配到某些状态,但返回的结果是空数组。我对Mongoose的查询方法是对吗?
答案 0 :(得分:2)
您根据架构设计使用EmployeeDetailSchema
引用employeeDetailsId
。所以你不能直接比较参考模型字段而不填充。您应首先填充然后比较和过滤文档,或者用户aggregate
功能可以实现您的目标。
可以试试这个:
EmployeeModel.aggregate([
{$lookup: {from: 'employeedetails', localField: 'employeeDetailsId',foreignField: '_id',as: 'details'}},
{$match: { $and:[{ "details.statusId": { "$exists": true } },{"details.statusId": req.params.statusId}]} }
]).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);
});
N.B:将字符串转换为 ObjectId req.params.statusId
{$match: {$and: [{"details.statusId": {"$exists": true}}, {"details.statusId": mongoose.Types.ObjectId(req.params.statusId)}]}}