我有一个事件模式:
owner: {
type: Schema.Types.ObjectId,
ref: 'User',
required: true
},
participants: [
{
type: Schema.Types.ObjectId,
ref: 'User'
}
],
createdOn: { type: Date, default: Date.now },
lastModified: { type: Date, default: Date.now },
active:{ type: Boolean, default: false },
eventDate: { type: Date },
startAt: { type: Date },
endAt : { type: Date },
timeZone:{ type: 'String', required: true }
我想插入事件,以使事件不会与其他事件重叠(例如:如果某个事件发生在2018-2-14,开始于3:00 am,结束于4:00 am,则此日期之间不应有任何事件3:00 AM和4:00 AM(此事件除外),但在该日期可能会有其他时段的事件,但不在3:00 AM到4:00 AM之间)
我尝试了以下逻辑,但似乎没有用。这个逻辑有什么问题:
const eventData = {
owner: req
.body
.owner
.trim(),
startAt: setTimeToDate(req.body.eventDate, req.body.startAt.trim(), req.body.timeZone),
endAt: setTimeToDate(req.body.eventDate, req.body.endAt.trim(), req.body.timeZone),
eventDate: moment(req.body.eventDate).toISOString(),
participants: req.body.participants,
active: true,
timeZone: req.body.timeZone
};
Events.find({
$and: [
{
"eventDate": new Date(eventData.eventDate)
}, {
$or: [
{
$and: [
{
"startAt": {
$lt: new Date(eventData.startAt)
}
}, {
"startAt": {
$lte: new Date(eventData.endAt)
}
}
]
}, {
$and: [
{
"endtAt": {
$gte: new Date(eventData.startAt)
}
}, {
"endtAt": {
$gt: new Date(eventData.endAt)
}
}
]
}
]
}
]
})
.exec(function (err, results) {
const count = results.length;
if (!count) {
const newEvent = new Events(eventData);
newEvent.save((err) => {
if (err) {
res
.status(400)
.json({success: false, message: 'Could not create this availability.'});
}
res
.status(200)
.send({success: true, message: 'Your availability on this date is created successfully.'});
});
}
});
最佳答案
好吧,我不确定,但我发现逻辑上有两个缺陷
基本上,您需要在新的startAt和endAt之间具有startAt或endAt的任何记录
在第一种情况下,您需要在新的startAt和endAt之间具有startAt时间的插槽,因此逻辑将是
startAt greater than new startAt and less than equal to new endAt
$and: [
{
"startAt": {
$gt: new Date(eventData.startAt)
}
}, {
"startAt": {
$lte: new Date(eventData.endAt)
}
}
]
另外,您想要在新的startAt之后和新的endAt之前具有endAt的记录,因此对于该逻辑
endAt greater than new startAt and less than equal to new endAt
$and: [
{
"endAt": {
$gt: new Date(eventData.startAt)
}
}, {
"endAt": {
$lte: new Date(eventData.endAt)
}
}
]
我认为这会起作用。
编辑好第三个条件是,在新StartAt之前开始并在新EndAt之后结束的插槽,因为它们不会落入上述条件
$and: [
{
"startAt": {
$lt: new Date(eventData.startAt)
}
}, {
"endAt": {
$gt: new Date(eventData.endAt)
}
}
]