简化此聚合管道?

时间:2019-01-14 20:27:52

标签: mongodb aggregation-framework

我有一个timetables馆藏,其中包含以下文档:

{ day: 'Mon', hour: '08:00', subject: 'Lab RP', room: 'D3-006' },
{ day: 'Mon', hour: '10:00', subject: 'PSAVC', room: 'A4-105' },
{ day: 'Mon', hour: '12:00', subject: 'Lab DSBM', room: 'D3-006' },
{ day: 'Tue', hour: '08:00', subject: 'TD', room: 'A4-105' },
{ day: 'Tue', hour: '10:00', subject: 'PSAVC', room: 'A4-105' },
{ day: 'Tue', hour: '11:00', subject: 'DSBM', room: 'A4-105' },
{ day: 'Tue', hour: '12:00', subject: 'RP', room: 'A4-105' },
{ day: 'Wed', hour: '08:00', subject: 'Lab PBE', room: 'C4-S10' },
{ day: 'Thu', hour: '08:00', subject: 'PBE', room: 'A4-105' },
{ day: 'Thu', hour: '10:00', subject: 'TD', room: 'A4-105' },
{ day: 'Thu', hour: '12:00', subject: 'PSAVC', room: 'A4-105' },
{ day: 'Fri', hour: '08:00', subject: 'RP', room: 'A4-105' },
{ day: 'Fri', hour: '10:00', subject: 'TD', room: 'A4-105' },
{ day: 'Fri', hour: '11:00', subject: 'DSBM', room: 'A4-105' }

并且我编写了一个自定义sort,其中类从当前日期开始以day/hour升序排列。即假设星期二10:30,第一节课是:

{ day: 'Tue', hour: '11:00', subject: 'DSBM', room: 'A4-105' },

最后一个:

{ day: 'Tue', hour: '10:00', subject: 'PSAVC', room: 'A4-105' },

这是我使用aggregation framework的工作代码:

db.timetables.aggregate([
  { $addFields: {
    '_vars.isoDayOfWeek': {
      $add: [{ $indexOfArray: [['Mon','Tue','Wed','Thu','Fri','Sat','Sun'], '$day'] }, 1]
    },
    '_vars.now': { $dateToParts: { date: new Date(), iso8601: true } },
    '_vars.hourMinute': { $split: ['$hour', ':'] },
  }},
  { $addFields: {
    '_vars.hour': { $toInt: { $arrayElemAt: ['$_vars.hourMinute', 0] } },
    '_vars.minute': { $toInt: { $arrayElemAt: ['$_vars.hourMinute', 1] } }
  }},
  { $addFields: {
    order: {
      $let: {
        vars: {
          offset: { $subtract: ['$_vars.isoDayOfWeek', '$_vars.now.isoDayOfWeek'] },
          ref: {
            $dateFromParts: {
              isoWeekYear: '$_vars.now.isoWeekYear',
              isoWeek: '$_vars.now.isoWeek',
              isoDayOfWeek: '$_vars.now.isoDayOfWeek',
              hour: '$_vars.hour',
              minute: '$_vars.minute'
            }
          }
        },
        in: {
          $cond: [
            { $or: [
              { $lt: ['$$offset', 0] },
              { $and: [
                { $eq: ['$$offset', 0] },
                { $or: [
                  { $gt: ['$_vars.now.hour', '$_vars.hour'] },
                  { $and: [
                    { $eq: ['$_vars.now.hour', '$_vars.hour'] },
                    { $gt: ['$_vars.now.minute', '$_vars.minute'] }
                  ]}
                ]}
              ]}
            ]},
            { $add: [
              '$$ref',
              { $multiply: [
                { $add: ['$$offset', 7] },
                24*60*60000
              ]}
            ]},
            { $add: [
              '$$ref',
              { $multiply: [
                '$$offset',
                24*60*60000
              ]}
            ]},
          ]
        }
      }
    }
  }},
  { $sort: { order: 1 } },
  { $project: {
    _id: 0,
    day: 1,
    hour: 1,
    subject: 1,
    room: 1
  }}
])

坦率地说,我觉得它太麻烦了。您能建议简化一下吗?谢谢

0 个答案:

没有答案