Запросы для встроенного объекта в массиве - PullRequest
0 голосов
/ 18 мая 2018

Я работаю над системой фильтров для страницы.У меня есть следующая структура схемы:

User: {
  firstName
  lastName
  email
  subscriptions: [
    {
      id: '5a687c7680eab407064c3990'
      plan: "TRIAL"
      startDate: '2018-03-01'
      endDate: '2018-04-01'
      status: 'EXPIRED'
    }
    {
      id: '5afacc040e53b4075dcdd600'
      plan: "BASIC"
      startDate: '2018-04-01'
      endDate: '2018-05-01'
      status: 'EXPIRED'
    }
    {
      id: '5afacc040e53b4075dcdd600'
      plan: "BASIC"
      startDate: '2018-05-01'
      endDate: '2018-06-01'
      status: 'CANCELLED'
    }
  ]
}

Мне нужно получить список пользователей, которые имеют:

  • firstName, lastName или адрес электронной почты 'john'
  • текущий статус подписки: EXPIRED
  • текущий план подписки: TRIAL

Это должно возвращать ноль.

Вот что я пробовал:

User.find({
  $or:
    [
      { firstName: { $regex: args.search, $options: 'i' } },
      { lastName: { $regex: args.search, $options: 'i' } },
      { email: { $regex: args.search, $options: 'i' } },
    ],
  $and:
    [
      { 'subscriptions.status': 'EXPIRED' },
      { 'subscriptions.plan': 'TRIAL' },
    ],
}).limit(limit).skip(skip);

Проблема в том, что мне нужен только поиск по последней подписке пользователя (той, которая имеет последнюю дату startDate), а не по всем объектам в массиве.Есть способ сделать это?У меня также есть виртуальное поле в схеме, но кажется, что вы не можете запросить виртуальное поле.

1 Ответ

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

Для выполнения этой операции вы должны попробовать агрегированный запрос ...

Сначала вам нужно будет

  1. $match firstName, lastName, email
  2. затем $unwind для сортировки подписки в соответствии с startDate
  3. , затем снова $match для получения плана и статуса

    db.collection.aggregate([
      {
        $match: {
          $or: [
            {
              firstName: {
                $regex: args.search,
                $options: "i"
              }
            },
            {
              lastName: {
                $regex: args.search,
                $options: "i"
              }
            },
            {
              email: {
                $regex: args.search,
                $options: "i"
              }
            }
          ]
        }
      },
      {
        $unwind: "$subscriptions"
      },
      {
        $sort: {
          "subscriptions.startDate": -1
        }
      },
      {
        $group: {
          _id: "$_id",
          subscriptions: {
            "$first": "$subscriptions"
          }
        }
      },
      {
        $match: {
          "subscriptions.status": "EXPIRED",
          "subscriptions.plan": "TRIAL"
        }
      },
    
    ])
    
...