Добрый день, я сделал дизайн с тремя таблицами, я не уверен, что это правильно, но кажется, что он делает то, что мне нужно, и в основном это нормально. Я сделал денормализацию, потому что записи будут выполняться в одну таблицу один раз в месяц (отчеты), а в другую (TimeReports), как один раз или, может быть, пару раз в месяц, а чтение будет происходить каждый день.
Мне даже нужна денормализация, или, возможно, ссылки ObjectId помогут? Я могу выполнять поиск, как я делаю по отчетам, я могу найти отдельные TimeReports и все 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 (отчет за этот месяц).
Как мне удалить TimeReport из User.reports?
Если я могу исключить отчеты из схемы пользователя, у меня все еще есть проблема с управлением обновлениями и удалением 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)
})
метод сложнее и выглядит ужасно.
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)
})
})
Не могли бы вы дать мне совет по поводу хорошего дизайна?