【发布时间】:2020-02-25 17:18:53
【问题描述】:
我正在尝试建立一个系统来记录时间表。对于每一天,员工可以根据分配给他们的不同任务记录不同的时间。我的时间表集合中的每个条目都包含一组单独的时间表条目。此集合的示例数据/模式:
[
{
"_id": "5db2c672620ed61854818ccd",
"EmployeeId": "5da9aed442e3070bbd9f7581",
"TimeSheet": [
{
"_id": "5db2c672620ed61854818ccf",
"TaskId": "5db14152e6537a05258bf573",
"Hours": "2.5",
"Remarks": "Test 2.5"
},
{
"_id": "5db2c672620ed61854818cce",
"TaskId": "5db1886ee6537a05258bf575",
"Hours": "11.5",
"Remarks": "Test 11.5"
}
],
"__v": 0
}
]
对于对应的Task集合,数据的驻留方式如下——
[
{
"_id": "5db14152e6537a05258bf573",
"EmployeeId": "5da9aed442e3070bbd9f7581",
"ProjectId": "5db141d9e6537a05258bf574",
"TaskName": "Finish the timesheet page",
"TaskDescription": "Write the front-end and back-end code to allow employees to record their timesheets."
},
{
"_id": "5db1886ee6537a05258bf575",
"EmployeeId": "5da9aed442e3070bbd9f7581",
"ProjectId": "5db141d9e6537a05258bf574",
"TaskName": "Learn Populate",
"TaskDescription": "Learn how MongoDB/Mongoose uses the equivalent of SQL joins"
},
{
"_id": "5db27e3ca2445c05255dbad0",
"EmployeeId": "5da9aed442e3070bbd9f7581",
"ProjectId": "5db141d9e6537a05258bf574",
"TaskName": "Timesheet save API",
"TaskDescription": "Code the API to save a timesheet to the database"
}
]
我正在尝试将任务详细信息(任务名称、任务描述和其他)添加到每个单独的任务时间表条目中。为此,我尝试在我的控制器中使用populate() 方法,就像这样 -
exports.findByEmployee = (req, res) => {
TimeSheet.find({ EmployeeId: req.query.EmployeeId })
.then(timesheets => {
timesheets.forEach((ts, ts_index) => {
ts.TimeSheet.forEach((item, index) => {
Task.findById(item.TaskId).populate('TaskId').exec((err, taskDetails) => {
item.TaskDetails = taskDetails;
})
});
})
res.send(timesheets);
}).catch(err => {
res.status(500).send({
message: err.message || "Some error occurred while retrieving timesheets."
});
});
}
但是,API 响应(用于获取所有时间表)在单个任务时间表部分中不包含名为 TaskDetails 的键。我的猜测是,由于函数调用的异步特性,res.send(timesheets) 部分在上面的部分有时间完成之前就被触发了。所以我的问题是,我该如何解决这个问题?总而言之,我希望任务集合中的任务详细信息以及通过 id 链接到任务的每个单独的时间表项。另外,这是使用populate() 的正确方法,还是有更好/更简单/更正确的方法可以解决我的问题?
编辑: 有人要求提供模型,所以这里是任务和时间表:
const mongoose = require('mongoose');
var ObjectId = mongoose.Schema.Types.ObjectId;
const TaskSchema = mongoose.Schema({
EmployeeId: ObjectId,
ProjectId: ObjectId,
TaskName: String,
TaskDescription: String
}, { collection: 'TASK' });
module.exports = mongoose.model('Task', TaskSchema);
const mongoose = require('mongoose');
var ObjectId = mongoose.Schema.Types.ObjectId;
const TimeSheetSchema = mongoose.Schema({
EmployeeId: ObjectId,
Date: Date,
TimeSheet: [
{
TaskId: {
type: ObjectId,
ref: 'TASK'
},
Hours: String,
Remarks: String
}
]
}, { collection: 'EMPLOYEE_TIMESHEET' });
module.exports = mongoose.model('TimeSheet', TimeSheetSchema);
【问题讨论】:
-
您可以在问题中添加 TimeSheet、Task 和 TaskDetails 模型吗?
-
@SuleymanSah 添加了。我没有用于 Task 和 TaskDetails 的单独模型,我将所有与任务相关的东西都保存到同一个集合中。
-
你在一个循环中循环访问db,当出现数百个集合时性能会受到严重影响。
标签: node.js mongodb express asynchronous mongoose