MongoDB показывает первое и последнее событие для каждого пользователя за каждый день - PullRequest
0 голосов
/ 09 октября 2018

Каждый раз, когда пользователь входит в систему или выходит из системы, событие сохраняется в монго.Пользователь может входить и / или выходить из системы несколько раз в день.

Например, Боб имеет вход в систему 2 раза и выход из системы 1 раз:

{
  username: ‘bob’,
  type: ‘login’,
  eventDate: ISODate(‘2018-09-21T12:39:50.676Z’)
}

{
  username: ‘bob’,
  type: ‘login’,
  eventDate: ISODate(‘2018-09-21T13:55:50.676Z’)
}

{
  username: ‘bob’,
  type: ‘logout,
  eventDate: ISODate(‘2018-09-21T22:10:50.676Z’)
}

И у Джеймса есть только 1 событие входа в систему:

{
  username: ‘james’,
  type: ‘login,
  eventDate: ISODate(‘2018-09-21T10:10:50.676Z’)
}

Я хотел бы выполнить запрос, который будет извлекать первый логин дня и последний выход дня для каждого пользователя для каждого дня (скажем, на прошлой неделе).

Таким образом, результат будет выглядеть так:

[{
  username: ‘bob’,
  firstLogin: ISODate(‘2018-09-21T12:39:50.676Z’),
  lastLogout: ISODate(‘2018-09-21T22:10:50.676Z’)
}

{
  username: ‘james’,
  firstLogin: ISODate(‘2018-09-22T10:19:50.676Z’),
  lastLogout: null,
}]

Я считаю, что мне приходится иметь дело с «агрегацией», но я не уверен.

Ответы [ 2 ]

0 голосов
/ 09 октября 2018

Вы можете достичь одним group.

Также работайте, когда у вас есть разные дни для одного и того же пользователя.

возвратите последнюю и первую дату на type.

протестировано на графическом интерфейсе MongoDB.

db.getCollection("loginDetail").aggregate([
  {
    $group: {
      _id: {
        username: "$username",
        year: { $year: "$eventDate" },
        month: { $month: "$eventDate" },
        day: { $dayOfMonth: "$eventDate" }
      },
      firstLogin: {
        $min: {
          $cond: [{ $and: [{ $eq: ["$type", "login"] }] }, "$eventDate", null]
        }
      },
      lastLogout: {
        $max: {
          $cond: [{ $and: [{ $eq: ["$type", "logout"] }] }, "$eventDate", null]
        }
      }
    }
  },
  {
      $project: {
          _id: 1,
          username : '$_id.username',
          firstLogin :1,
          lastLogout :1
          }
      }
]);
0 голосов
/ 09 октября 2018

Используя два уровня $group: (MongoDB V3.2.18)

Я считаю, userName уникально.

  1. $sort eventDate first.
  2. $group by userName и введите .
  3. $project для дифференциации firstLogin и lastLogin .
  4. $group снова userName для окончательного результата.
db.getCollection('test').aggregate([
  {$sort: {'eventDate' : 1}},
  {
    "$group" : {
        _id: {"username" : "$username", "type": "$type"},
        eventDate: {$push: "$eventDate"}
    }
  },
  {
    $project : {
      _id:1,
      eventDate:1,
      firstLogin: {
        $cond: [ { "$eq": ["$_id.type", "login" ]}, { $arrayElemAt: [ "$eventDate", 0 ] }, null]
      },
      lastLogout: {
        $cond: [ { "$eq": ["$_id.type", "logout" ]}, { $arrayElemAt: [ "$eventDate", -1 ] }, null]
      }
    }
  },
  {
    "$group" : {
        _id: "$_id.username",
        firstLogin: {$first: "$firstLogin"},
        lastLogout: {$last: "$lastLogout"}
    }
  }
]);

Выход:

/* 1 */
{
    "_id" : "james",
    "firstLogin" : ISODate("2018-09-21T10:10:50.676Z"),
    "lastLogout" : null
}

/* 2 */
{
    "_id" : "bob",
    "firstLogin" : ISODate("2018-09-21T12:39:50.676Z"),
    "lastLogout" : ISODate("2018-09-21T22:10:50.676Z")
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...