美好的一天,我已经完成了一个包含三个表的设计,我不确定它是否正确,但是看起来像它可以满足我的需要,而且大多数情况下还可以。我之所以进行非规范化,是因为每个月一次在一个表中(报告)在表中写入数据,而每月一次或可能几次在另一个表(TimeReports)中写入数据,并且每天都会进行读取。
我是否甚至需要进行非规范化,或者ObjectId链接可以解决问题?我可以像按报告一样执行搜索,可以按特定用户查找单个TimeReports和所有TimeReports,所以也许这里不需要非规范化吗?但是我确实需要在报告中显示一些时间报告。
所以我有这个:
let TimeReportSchema = new Schema({
hours: Number,
rate: Number,
sum: Number,
companyId: {type: mongoose.Schema.Types.ObjectId, ref: 'Company'},
companyName: String,
userId: {type: mongoose.Schema.Types.ObjectId, ref: 'User'},
reportId: {type: mongoose.Schema.Types.ObjectId, ref: 'Report'},
date: {type: Date, default: Date.now},
updated: {type: Boolean, default: false}
})
let ReportSchema = new Schema({
userId: {type: mongoose.Schema.Types.ObjectId, ref: 'User'},
director: {type: mongoose.Schema.Types.ObjectId, ref: 'User'},
invoice: {type: String, default: ""},
time_reports: [TimeReportSchema],
summary: {type: Number, default: 0},
date: {
type: Date,
default: Date.now
}
})
var UserSchema = new Schema({
name: {
type: String,
required: true
},
email: {
type: String,
unique: true,
required: true
},
...
reports: [ReporSchema],
companyId: {type: mongoose.Schema.Types.ObjectId, ref: 'Company'},
positionId: {type: mongoose.Schema.Types.ObjectId, ref: 'Position'},
});
我每个月创建一次报表并推入每个用户,而不是用户创建TimeReports,它们还会推到User.reports和Report(本月报表)。
如何从User.reports中删除TimeReport? 如果我可以将报告从用户架构中排除,则仍然存在如何管理更新以及如何从报告中删除TimeReports的问题。
app.delete('/time-report/:id', async (req, res) => {
let userId;
await TimeReport.findById(req.params.id, (error, report) => {
checkForError(res, error);
userId = report.userId;
console.log(report, 'report1');
})
await TimeReport.remove({
_id: req.params.id
}, (error, report) => {
checkForError(res, error)
})
// User.update({_id: userId},
// {$pull: {'reports.time_reports': {_id: req.params.id}}})
// res.send({
// success: true
// })
// that didn't worked
})
app.get('/time-report/:id', (req, res) => {
let id = req.params.id
TimeReport.findById(id, (err, reports) => {
res.send(reports)
})
})
app.get('/time-reports/:userId', (req, res) => {
TimeReport.find({userId: req.params.userId}, (err, reports) => {
console.log(reports, 'reports')
res.send(reports)
}).sort({date:-1})
})
app.post('/time-report/:id', async (req, res) => {
var begin = moment().startOf('month')
var end = moment(begin).endOf('month')
let query = {
userId: req.params.id,
date: {
$gte: begin.toDate(),
$lt: end.toDate()
}
}
let hours = Number(req.body.hours)
let rate = Number(req.body.rate)
let sum = hours * rate
await Report.findOne(query, async (error, report) => {
console.log(report, 'report for id')
let reportId = report._id
newTimeReport = new TimeReport({
hours, rate, sum, companyId, company, userId, reportId
})
newTimeReport.save((error) => {
checkForError(res, error)
report.time_reports.push(newTimeReport)
report.summary += sum
report.save((error) => {
checkForError(res, error)
})
})
})
User.findById(req.params.id, (err, user) => {
user.reports.forEach((report, index) => {
if(report.date.getMonth() === begin.toDate().getMonth()) {
report.summary += sum
report.time_reports.push(newTimeReport)
}
})
user.save((error) => {
checkForError(res, error)
})
res.send(user)
})
put方法更复杂并且看起来很糟糕。
app.put('/time-report/:id', async (req, res) => {
let id = req.params.id;
let reportId;
let oldSum;
let newSum;
TimeReport.findById(id, async (err, report) => {
reportId = report.reportId
oldSum = report.sum
report.hours = Number(req.body.hours)
report.rate = Number(req.body.rate)
report.company = req.body.companyName
report.companyId = req.body.companyId
report.sum = Number(req.body.hours) * Number(req.body.rate)
report.updated = true
report.save((error) => {
})
Report.findById(reportId, (error, report) => {
report.summary -= oldSum
report.summary += newSum
for(let j = 0; j < report.time_reports.length; j++) {
if(report.time_reports[j]._id == id) {
report.time_reports[j].hours = Number(req.body.hours)
report.time_reports[j].rate = Number(req.body.rate)
report.time_reports[j].sum = newSum
}
}
report.save((error) => {
})
})
User.findById(report.userId, (err, user) => {
loop1:
for(let i = 0; i < user.reports.length; i++) {
loop2:
for(let j = 0; j < user.reports[i].time_reports.length; j++) {
if(user.reports[i].time_reports[j]._id == id) {
user.reports[i].summary -= oldSum
newSum = Number(req.body.hours) * Number(req.body.rate)
user.reports[i].summary += newSum
user.reports[i].time_reports[j].hours = Number(req.body.hours)
user.reports[i].time_reports[j].rate = Number(req.body.rate)
user.reports[i].time_reports[j].sum = newSum
user.reports[i].time_reports[j].company = req.body.companyName
user.reports[i].time_reports[j].companyId = req.body.companyId
user.reports[i].time_reports[j].updated = true
break loop1;
}
}
}
user.save((error) => {
})
})
res.send(report)
})
})
您能给我一个好的设计建议吗?