我们将从查找与 newDocument 的所有交集开始未来的日期)
let newBookingStartDate = newBooking.startDate;
let newBookingEndDate = newBooking.endDate ? newBooking.endDate : new Date().setYear(3000);
现在开始查询:
let results = await db.collection.aggregate([
{
$addFields: {
tmpEndDate: {
$cond: [
{$ne: ["$endDate", null]},
"$endDate",
newBookingEndDate
]
}
}
},
{
$match: {
$or: [
{
$and: [
{
startDate: {$lt: newBookingStartDate},
},
{
tmpEndDate: {$gt: newBookingStartDate}
},
]
},
{
$and: [
{
startDate: {$gte: newBookingStartDate},
},
{
startDate: {$lt: newBookingEndDate}
},
]
},
],
}
},
])
我们通过分两种情况来匹配文档:
-
document.startDate 低于newDocument.startDate - 在这种情况下,我们只需要检查document.endDate 是否大于newDocument.startDate,如果是则我们有一个交集
-
document.startDate 大于或等于newDocument.startDate - 在这种情况下,我们只需要检查document.startDate 是否小于newDocument.endDate,我们将再次得到一个交集
现在我们需要遍历我们找到的文档并通过运行相同的查询来计算它们之间的交集:
for (let i = 0; i < results.length; i++) {
let doc = results[i];
let otherIds = results.map(val => val._id);
let docStartDate = doc.startDate;
let docEndDate = doc.endDate ? doc.endDate : new Date().setYear(3000);
let count = await db.collection.aggregate([
{
$match: {
_id: {$in: otherIds}
}
},
{
$addFields: {
tmpEndDate: {
$cond: [
{$ne: ["$endDate", null]},
"$endDate",
docEndDate
]
}
}
},
{
$match: {
$or: [
{
$and: [
{
startDate: {$lt: docStartDate},
},
{
tmpEndDate: {$gt: docStartDate}
},
]
},
{
$and: [
{
startDate: {$gte: docStartDate},
},
{
startDate: {$lt: docEndDate}
},
]
},
],
}
},
{
$count: "count"
}
])
if (count[0].count >= 3){
return false;
}
}
如果任何计数结果为 3 或更大(3 因为我没有从数组中删除当前文档 ID,并且它总是与自身相交)返回 false,因为插入新文档会使您超过阈值。