Mongoose / Mongo Count Объекты в массиве ссылок созданного - PullRequest
0 голосов
/ 03 мая 2018

В моей коллекции пользователей у меня есть два поля, подобные этим:

  assignedTickets: [
    {
      type: mongoose.Schema.ObjectId,
      ref: 'Ticket',
      index: true,
    },
  ],
  resolvedTickets: [
    {
      type: mongoose.Schema.ObjectId,
      ref: 'Ticket',
      index: true,
    },
  ],

Для каждого из этих полей я пытаюсь получить количество объектов на основе даты создания каждого объекта. Например, на 2018-05-03 я хочу знать, сколько билетов было создано на эту дату.

Я пытался это:

const start = new Date();
start.setHours(0, 0, 0, 0);
const end = new Date();
end.setHours(23, 59, 59, 999);

userSchema.statics.assignedToday = function () {
  return this.aggregate([
    {
      $lookup: {
        from: 'tickets', localField: '_id', foreignField: 'assignee_id', as: 'tickets',
      },
    },
    { $unwind: '$tickets' },
    { $match: { createdAt: { $gte: start, $lt: end } } },
    {
      $group: {
        _id: {
          year: { $year: '$createdAt' },
          month: { $month: '$createdAt' },
          day: { $dayOfMonth: '$createdAt' },
        },
        count: { $sum: 1 },
      },
    },
  ]);
};

Но я получаю только пустой массив []

Если я закомментирую часть $ match конвейера, я получу:

[
  {
    "_id": {
      "year": 2018,
      "month": 5,
      "day": 2
    },
    "count": 178
  }
]

Но это общее количество ВСЕХ билетов (не только назначенных), и данные возвращаются только 2 мая (это дата, когда была создана коллекция Билетов).

Вот пример пользовательского документа:

{
  "assignedTickets": [
    "5ae9c2d59c7fcb540cca0b9e",
    "5ae9c3649c7fcb540cca0ba0",
    "5ae9c3849c7fcb540cca0ba2",
    ...
  ],
  "resolvedTickets": [
    "5ae9c2d59c7fcb540cca0b9d",
    "5ae9c2d59c7fcb540cca0b9e",
    "5ae9c3299c7fcb540cca0b9f",
    ...
  ],
  "_id": "5ae763a6ed455639802e8f1a",
  "firstName": "NAME",
  "lastName": "LASTNAME",
  "email": "EMAIL",
  "createdAt": "2018-04-30T18:42:46.582Z",
  "updatedAt": "2018-05-03T15:29:13.955Z",
  "__v": 0,
}

Вот пример документа билета:

{
  "_id": "5ae9c2d59c7fcb540cca0b9e",
  "ticket_id": 119472,
  "type": "resolved",
  "status": "Solved",
  "assignee_email": "EMAIL",
  "createdAt": "2018-05-01T13:53:25.639Z",
  "updatedAt": "2018-05-03T04:06:22.852Z",
  "__v": 0,
  "assignee_id": "5ae763a6ed455639802e8f1a"
}

1 Ответ

0 голосов
/ 04 мая 2018

Мне удалось выяснить правильный синтаксис для правильного возврата результатов:

const start = new Date().setHours(0, 0, 0, 0);
const end = new Date().setHours(23, 59, 59, 999);

userSchema.statics.getAssigned = function () {
  return this.aggregate([
    {
      $lookup: {
        from: 'tickets',
        localField: 'assignedTickets',
        foreignField: '_id',
        as: 'assigned_tickets',
      },
    },
    { $unwind: '$assigned_tickets' },
    { $match: { 'assigned_tickets.createdAt': { $gte: new Date(start), $lt: new Date(end) } } },
    {
      $group: {
        _id: {
          year: { $year: '$assigned_tickets.createdAt' },
          month: { $month: '$assigned_tickets.createdAt' },
          day: { $dayOfMonth: '$assigned_tickets.createdAt' },
          _id: '$assigned_tickets.assignee_id' },
        },
        count: {
          $sum: 1,
        },
      },
    },
  ]);
};

В исходной функции было несколько проблем.

Во-первых, при поиске я ссылался на поле _id для localField, но это должно было быть assignedTickets (специально для получения назначенных билетов), а foreignField, который был assignee_id, должен был быть _id.

Второй проблемой были даты, переданные на стадию $ match, на которые этот ТАК вопрос поможет мне ответить .

Наконец, на этапе $ match необходимо сослаться на псевдоним assigned_tickets на этапе $ lookup, который мандар помог мне осознать.

...