javascript - 使用 $or 和 $and 进行 MongoDB 聚合
问题描述
我有以下 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 的那个是您不需要的异常值。
蒙戈游乐场
推荐阅读
- ios - 如何在 SCNScene 中旋转对象并替换该对象?
- vue.js - 从计算数据访问 Vue 组件道具
- amazon-s3 - Airflow/minio:如何使用 minio 作为本地 S3 代理来处理从 Airflow 发送的数据?
- python - 如何在graphene-python DjangoObjectType中获取模型的当前实例
- java - 使用 Selenium 在 Chrome 上处理“您与此站点的连接不是私有的”弹出窗口
- javascript - 如何解决“不变违规:此导航器缺少导航道具”?
- google-cloud-messaging - 是否必须从 GCM 迁移到 FCM 以获取 chrome/浏览器通知
- python - 如何将列表中的每个项目连接到特定的 URL?
- mysql - 使用紧凑的 laravel 显示数据
- java - 如何修复 Netbeans 中的“未找到 Log4j 2 配置文件”?