在聚合管道中将文档字段用作JS对象字段名称

时间:2018-08-16 13:29:41

标签: mongodb mongodb-query aggregation-framework

我有一个名为tasksCountMap的JS对象:

const tasksCountMap = {
   'Freshman': 46,
   'Senior': 10
}

,我需要在聚合管道“ Freshman”,“ Senior”中获取每个用户类型的任务计数,该文档字段称为gradeLevel。我正在尝试这样做:

status: {
        $let: {
          vars: {
            tasksCount: tasksCountMap['$gradeLevel'],
            completedTasksCount: '$completedTasksCount[0].count'
          },
          in: {
            $cond: {
              if: { $or: [
                { $eq: ['$$tasksCount', '$$completedTasksCount'] },
                { $lte: ['$$tasksCount', '$$completedTasksCount'] },
              ]},
              then: 'On track',
              else: 'High priority'
            }
          }
        }
      }

'$completedTasksCount[0].count'也不适用...

有人可以显示出正确的方法吗?

所有管道:

{
    $match: {
      type: 'student',
      counselorUserName: username
    },
    $project: {
      username: '$username',
      email: '$email',
      phone: '$phone',
      fullName: '$fullName',
      gradeLevel: {
        $switch: {
          branches: [{
              case: {
                $eq: ['$gradeLevel', '9']
              },
              then: 'Freshman'
            },
            {
              case: {
                $eq: ['$gradeLevel', '10']
              },
              then: 'Sophomore'
            },
            {
              case: {
                $eq: ['$gradeLevel', '11']
              },
              then: 'Junior'
            },
            {
              case: {
                $eq: ['$gradeLevel', '12']
              },
              then: 'Senior'
            }
          ],
          default: "Freshman"
        }
      }
    },
    $lookup: {
      from: 'RoadmapTasksCompleted',
      let: {
        username: '$username',
        gradeLevel: '$gradeLevel'
      },
      pipeline: [{
          $match: {
            monthToComplete: {
              $in: prevMonthsNames
            },
            $expr: {
              $and: [{
                  $eq: ['$username', '$$username']
                },
                {
                  $eq: ['$gradeLevel', '$$gradeLevel']
                }
              ]
            }
          }
        },
        {
          $count: 'count'
        }
      ],
      as: 'completedTasksCount'
    },
    $project: {
      username: '$username',
      email: '$email',
      phone: '$phone',
      fullName: '$fullName',
      completedTask: { $arrayElemAt: ['$completedTasksCount', 0] },
      status: {
        $let: {
          vars: {
            tasksCount: tasksCountMap['$gradeLevel'],
            completedTasksCount: '$completedTasksCount[0].count'
          },
          in: {
            $cond: {
              if: { $or: [
                { $eq: ['$$tasksCount', '$$completedTasksCount'] },
                { $lte: ['$$tasksCount', '$$completedTasksCount'] },
              ]},
              then: '$$tasksCount',
              else:'$$tasksCount'
            }
          }
        }
      }
    }
    $limit: 10,
    $skip: 10,
  }

1 个答案:

答案 0 :(得分:1)

您必须将js映射移到聚合管道中,才能访问该映射。

我将$project阶段一分为二,并自由地清理了状态计算。

类似

{"$project":{
  "username":"$username",
  "email":"$email",
  "phone":"$phone",
  "fullName":"$fullName",
  "completedTask":{"$arrayElemAt":["$completedTasksCount",0]},
  "tasksCountMap":[{"k":"Freshman","v":46},{"k":"Senior","v":10}]
}},
{"$addFields":{
  "status":{
    "$let":{
      "vars":{
        "tasksCount":{
          "$arrayElemAt":[
            "$tasksCountMap.v",
            {"$indexOfArray":["$tasksCountMap.k","$gradeLevel"]}
           ]
         },
        "completedTasksCount":"$completedTask.count"
      },
      "in":{
        "$cond":{
          "if":{"$lte":["$$tasksCount","$$completedTasksCount"]},
          "then":"$$tasksCount",
          "else":"$$completedTasksCount"
        }
      }
    }
  }
}}