MongoDB聚合管道 - 按用户对组进行分组但保持计数

时间:2018-05-04 21:23:28

标签: node.js mongodb lookup aggregation

我有一个这样的用户架构(简化以便于阅读):

const userSchema = new Schema({
  firstName: String,
  lastName: String,
  assignedTickets: [
    {
      type: mongoose.Schema.ObjectId,
      ref: 'Ticket',
      index: true,
    },
  ],
  resolvedTickets: [
    {
      type: mongoose.Schema.ObjectId,
      ref: 'Ticket',
      index: true,
    },
  ],
}, {
  timestamps: true,
});

这样的故障单架构:

const ticketSchema = new Schema({
  ticket_id: {
    type: Number,
    required: true,
    index: true,
  },
  type: {
    type: String,
    required: true,
  },
  status: {
    type: String,
    required: true,
  },
  assignee_email: {
    type: String,
    required: true,
    index: true,
  },
  assignee_id: {
    type: mongoose.Schema.ObjectId,
    ref: 'User',
  },
}, {
  timestamps: true,
});

示例用户文档是:

{
    "_id": "5aeb6b71709f43359e0888bb", 
    "assignedTickets": ["5aeb6ba7709f43359e0888bd", "5aeb6bf3709f43359e0888c2", "5aec7e0adcdd76b57af9e889"], 
    "resolvedTickets": ["5aeb6bc2709f43359e0888be", "5aeb6bc2709f43359e0888bf"], 
    "firstName": "Name", 
    "lastName": "Surname", 
}

示例故障单文档是这样的:

{
    "_id": "5aeb6ba7709f43359e0888bd", 
    "ticket_id": 120292, 
    "type": "assigned", 
    "status": "Pending", 
    "assignee_email": "email@gmail.com", 
    "assignee_id": "5aeb6b71709f43359e0888bb", 
    "createdAt": "2018-05-02T20:05:59.147Z", 
    "updatedAt": "2018-05-03T20:05:59.147Z", 
}

运行此查询

const today = moment().startOf('day').endOf('day').valueOf();
const fiveDAgo = moment().subtract(5, 'd').startOf('day').valueOf();

userSchema.statics.getAssigned = function (req) {
  return this.aggregate([
    { $match: { organization: req.user.organization._id } },
    {
      $lookup: {
        from: 'tickets', localField: 'assignedTickets', foreignField: '_id', as: 'assigned_tickets',
      },
    },
    { $unwind: '$assigned_tickets' },
    { $match: { 'assigned_tickets.createdAt': { $gte: new Date(fiveDAgo), $lt: new Date(today) } } },
    {
      $group: {
        _id: {
          groupDate: {
            $dateFromParts: {
              year: { $year: '$assigned_tickets.createdAt' },
              month: { $month: '$assigned_tickets.createdAt' },
              day: { $dayOfMonth: '$assigned_tickets.createdAt' },
            },
          },
          _id: '$assigned_tickets.assignee_id',
        },
        ticketCount: {
          $sum: 1,
        },
      },
    },
    {
      $project: {
        _id: '$_id._id',
        date: '$_id.groupDate',
        count: '$ticketCount',
      },
    },
  ]);
};

返回以下结果:

[ 
  {
      _id: 5aec9179de6577dc027bf598, 
      date: 2018-05-04T00: 00: 00.000Z, 
      ticketCount: 12
  },
  {
      _id: 5aeb6b71709f43359e0888bb,
      groupDate: 2018-05-04T00: 00: 00.000Z,
      ticketCount: 25
  },
  {
      _id: 5aec8c439b8730bf8c7c616c,
      groupDate: 2018-05-04T00: 00: 00.000Z,
      ticketCount: 9
  },
  {
      _id: 5aeb6b71709f43359e0888bb,
      groupDate: 2018-05-03T00: 00: 00.000Z,
      ticketCount: 1
  },
  {
      _id: 5aeb6b71709f43359e0888bb,
      groupDate: 2018-05-02T00: 00: 00.000Z,
      ticketCount: 1
  }

]

这些结果可准确计算过去五天内每位用户分配的门票数量。我想重新格式化数据,以便结果为每个用户返回一个对象,每个日期有一个数组,而不是一个对象。

例如,期望的结果如下所示:

[
  {
    _id: '5aec9179de6577dc027bf598',
    data: [
      {
        date: '2018-05-04T00: 00: 00.000Z',
        ticketCount: 12
      }
    ]
  },
  {
    _id: '5aeb6b71709f43359e0888bb',
    data: [
      {
        groupDate: '2018-05-04T00: 00: 00.000Z',
        ticketCount: 25
      },
      {
        groupDate: '2018-05-03T00: 00: 00.000Z',
        ticketCount: 1
      },
      {
        groupDate: '2018-05-02T00: 00: 00.000Z',
        ticketCount: 1
      }
    ]
  },
  {
    _id: '5aec8c439b8730bf8c7c616c',
    data: [
        'groupDate': "2018-05-04T00: 00: 00.000Z",
        'ticketCount': 9
    ]
  }
]

我如何按用户对数据进行分组而不会丢失每个日期的计数?

0 个答案:

没有答案