假设我有此数据:
[{
"name": "New Training1",
"participants": ["5d2eca379b0d361b18d2f3d0", "5d31290c21729014a0bdd0ba"],
"schedule": [{
"start": "2019-10-07T12:00:00.000Z",
"end": "2019-10-07T14:00:00.000Z"
}]
}, {
"name": "New Training2",
"participants": ["5d2eca379b0d361b18d2f3d0"],
"schedule": [{
"start": "2019-10-07T14:00:00.000Z",
"end": "2019-10-07T15:00:00.000Z"
}]
}, {
"name": "New Training3",
"participants": ["5d31290c21729014a0bdd0ba"],
"schedule": [{
"start": "2019-10-07T14:00:00.000Z",
"end": "2019-10-07T16:00:00.000Z"
}]
}]
我想做的是,当我尝试将ID为5d2eca379b0d361b18d2f3d0
的参与者添加到培训New Training3
时,应用程序将抛出错误,表明日程安排存在冲突,并且将返回有冲突的时间表。根据上面的数据,系统必须返回此训练,因为它的时间表有冲突:
{
"name": "New Training2",
"participants": ["5d2eca379b0d361b18d2f3d0"],
"schedule": [{
"start": "2019-10-07T14:00:00.000Z",
"end": "2019-10-07T15:00:00.000Z"
}
}
这是我到目前为止所拥有的。
培训模式:
const mongoose = require('mongoose');
const ScheduleSchema = require('../models/schedule.model').schema;
const TrainingSchema = new mongoose.Schema(
{
name: {
type: String,
unique: true,
required: true
},
participants: [{ type: mongoose.Schema.ObjectId, ref: 'Participant' }],
schedule: [ScheduleSchema]
},
{
versionKey: false,
timestamps: true
}
);
module.exports = mongoose.model('Training', TrainingSchema);
参与者模型:
const mongoose = require('mongoose');
const ParticipantSchema = new mongoose.Schema(
{
name: {
type: String,
required: true
}
}
);
时间表模型
const mongoose = require('mongoose');
const ScheduleSchema = new mongoose.Schema(
{
start: {
type: Date,
required: true
},
end: {
type: Date,
required: true
}
},
{
versionKey: false,
timestamps: false
}
);
module.exports = mongoose.model('Schedule', ScheduleSchema);
如果我在给定的participantId
的训练中添加了trainingId
的实用性,则获得时间表重叠的训练的功能:
const model = require('../models/training.model');
exports.participantScheduleOverlaps = async (trainingId, participantId) => {
return new Promise((resolve, reject) => {
model.find(
);
});
};
我需要构建MongoDB查询来查找重叠的时间表。谢谢。
答案 0 :(得分:1)
尝试这个。
const mongoose = require('mongoose')
const Schema = mongoose.Schema
const util = require("util")
mongoose.connect("mongodb://localhost/mongoose-doc", { useNewUrlParser: true })
const ScheduleSchema = new Schema(
{
start: {
type: Date,
required: true
},
end: {
type: Date,
required: true
}
},
{
versionKey: false,
timestamps: false
}
);
const TrainingSchema = new Schema(
{
name: {
type: String,
unique: true,
required: true
},
participants: [{ type: mongoose.Schema.ObjectId, ref: 'Participant' }],
schedule: [ScheduleSchema]
},
{
versionKey: false,
timestamps: true
}
);
const TrainingModel = mongoose.model("Training", TrainingSchema);
const ParticipantSchema = new Schema(
{
name: {
type: String,
required: true
}
}
);
const ParticipantModel = mongoose.model("Participant", ParticipantSchema)
async function participantScheduleOverlaps(trainingId, participantId) {
try {
const trainingWeFound = await TrainingModel.aggregate([
{
$match:{
_id: mongoose.Types.ObjectId(trainingId)
}
},
{
$unwind: "$schedule"
}
]).exec()
const otherTrainingModules = await TrainingModel.aggregate(
[
{
$match:{
$and:[
{
_id:{
$ne: mongoose.Types.ObjectId(trainingId)
}
},
{
participants: {
$in: [mongoose.Types.ObjectId(participantId)]
}
}
]
}
},
{
$unwind: "$schedule"
}
]
).exec()
const overlapping = otherTrainingModules.filter((otherelem) => {
return trainingWeFound.filter(foundelem => {
(
Date.parse(otherelem.start) < Date.parse(foundelem.start)
&&
Date.parse(foundelem.start) < Date.parse(otherelem.end)
) || (
Date.parse(otherelem.start) < Date.parse(foundelem.end)
&&
Date.parse(foundelem.end) < Date.parse(otherelem.end)
)
})
})
console.log("overlapping", overlapping)
} catch(error){
console.log(error)
}
}
participantScheduleOverlaps("5d395604eb41824b5feb9c84", "5d31290c21729014a0bdd0ba")
答案 1 :(得分:0)
这是我针对可能有相同或相关问题的任何人的解决方案:
exports.participantScheduleOverlaps = async (trainingId, participantId) => {
return new Promise((resolve, reject) => {
model.findById(trainingId, (error, item) => {
const result = {
overlap: false,
ranges: []
};
if (error) {
reject(utils.buildErrObject(422, error.message));
}
if (item) {
for (const schedule of item.schedule) {
model.find(
{
_id: { $ne: trainingId },
participants: { $eq: participantId },
'schedule.end': { $gt: schedule.start },
'schedule.start': { $lt: schedule.end }
},
(err, items) => {
if (err) {
reject(utils.buildErrObject(422, err.message));
}
if (items.length > 0) {
result.overlap = true;
result.ranges.push(
...items.map(data => {
return data.schedule;
})
);
}
resolve(result);
}
);
}
} else {
resolve(result);
}
});
});
};