Трубопровод агрегации MongoDB - группировать группу по пользователю, но поддерживать счет - PullRequest
0 голосов
/ 05 мая 2018

У меня есть такая схема пользователя (упрощена для удобства чтения):

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
    ]
  }
]

Как я могу сгруппировать данные по пользователю, не теряя счет за дату?

...