[英]MongoDB Aggregation with $or and $and
我有以下 MonogoDb 集合
ShiftMgmt.shiftSchema = new mongoose.Schema({
assignedUser: { type: mongoose.Schema.Types.ObjectId, required: true, ref: 'users' },
shiftType: { type: mongoose.Schema.Types.ObjectId, required: true, ref: 'shiftTypes' },
team: { type: mongoose.Schema.Types.ObjectId, required: true, ref: 'teams' },
startDate: { type: Number, required: true },
endDate: { type: Number, required: true }
});
我想获得与给定时间跨度重叠的给定 ShiftType 的所有班次。
假设从 2021-07-19 (1626652800000) 到 2021-07-23 (1626998400000)
[
{
'$match': {
'startDate': {
'$gte': 1626652800000
},
'endDate': {
'$lte': 1626998400000
},
'shiftType': new ObjectId('60a36ea2e2f5035b26f23430')
}
}
]
以上管道将返回在给定时间跨度内开始和结束的每个班次。 但我也想获得开始和结束日期与时间跨度重叠的所有班次。
因此,例如,我希望它还可以找到从 2021-07-16 开始但将在 2021-07-21 结束的班次以及将在 2021-07-20 开始并于 2021-07-25 结束的班次.
我想要实现这一点,我需要 $and 和 $or 在我的管道中,但是我在找到正确的语法时遇到了问题。 到目前为止,这是我的非工作管道:
let date1 = 1626652800000 // 2021-07-19
let date2 = 1627041600000 // 2021-07-23
[
{
'$match': {
'$or': [
'$and': [ // shift lies betweend dates
'startDate': {
'$gte': date1
},
'endDate': {
'$lte': date2
}
],
'$and': [ // shift starts before timespan and ends in time span
"startDate": {
'$lte': date1
},
"endDate" {
'$gte': date1
}
],
'$and': [ // shift starts in timespan and ends after time span
"startDate": {
'$lte': date2
},
"endDate" {
'$gte': date2
}
],
'$and': [ // shift starts before timespand and ends after time span
"startDate": {
'$lte': date1
},
"endDate" {
'$gte': date2
}
]
],
'shiftType': ObjectId('60a36ea2e2f5035b26f23430')
}
}
]
解决方案感谢 Koodies 我能够像这样解决它:
[
{
'$match': {
'$or': [
{
'startDate': {
'$gte': 1625443200000,
'$lte': 1625788800000
}
}, {
'endDate': {
'$lte': 1625788800000,
'$gte': 1625443200000
}
}, {
'$and': [
{
'startDate': {
'$lte': 1625443200000
}
}, {
'endDate': {
'$gte': 1625788800000
}
}
]
}
],
'shiftType': new ObjectId('60a278355c7462f42b3d7895')
}
}
]
您正朝着正确的方向前进,但您无需使用 $and。 这是您的逻辑可以派生的方式,只需替换 startTime 和 endTime。
db.collection.aggregate([
{
$match: {
"$or": [
{
"startDate": {
"$gte": startTime,
"$lte": endTime
}
},
{
"endDate": {
"$lte": endTime,
"$gte": startTime
}
}
]
}
}
])
我在 mongo playground 上创建了一个包含 5 个文档的快速示例。 带有计数器 4 和 5 的那个是您不需要的异常值。
蒙戈游乐场
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.