Как рассчитать время сеансов на mongodb - PullRequest
0 голосов
/ 12 апреля 2020

У меня есть ситуация:

У меня есть данные, хранящиеся в коллекции mongodb (называемой веб-журналами) mongodb со следующей структурой:

account access_time profile_id и т. Д.

В этой коллекции хранятся журналы навигации пользователей через прокси-сервер, поэтому данных очень много.

Мне нужно сгруппировать по аккаунту и access_time, но отсортировать по access_time *

{ account: "aaaa", access_time: "2020-04-04 12:27:00" }     //First Session
{ account: "aaaa", access_time: "2020-04-04 12:30:21" }     
{ account: "aaaa", access_time: "2020-04-04 12:31:20" }     //Ends of First session

{ account: "aaaa", access_time: "2020-04-04 12:40:20" }     //Second Session
{ account: "aaaa", access_time: "2020-04-04 12:41:25" }
{ account: "aaaa", access_time: "2020-04-04 12:42:30" }     //Ends of Second session

Как я могу получить сессии для каждого пользователя. Сеансы рассчитываются следующим образом:

Когда пользователь запрашивает первый запрос, я создаю первый сеанс,

Когда сеанс заканчивается?

Если следующий журнал access_time нет ' t больше 5 минут, я должен взять следующий журнал в качестве текущего и повторить процесс, я сохраняю первый журнал access_time для вычисления общего времени сеанса.

Когда следующий журнал access_time больше, сеанс заканчивается вычисленным временем = текущий журнал access_time (NOT CURRENT + 1 ACCESS_TIME LOG) - первое время access_log

Мне нужен какой-либо способ для вычисления этого на конвейере mongodb или другим способом, потому что из php я пробовал пути, но плохо с памятью и т. д.

1 Ответ

0 голосов
/ 13 апреля 2020

Следующая агрегация вычисляет сеансы и возвращает сеанс start и end раз (для каждого сеанса). Обратите внимание, что я преобразовал поле строки access_time в объект date для упрощения расчетов.

const FIVE_MINS = 5 * 60 * 1000    // time in milliseconds

db.collection.aggregate( [
  { 
      $sort: { account: 1, access_time: 1 } 
  },
  { 
      $group: { 
          _id: "$account", 
          access_times: { $push: { $toDate: "$access_time" } } 
      } 
  },
  { 
      $addFields: { 
          sessions: { 
              $reduce: { 
                   input: "$access_times", 
                   initialValue: { 
                       first: { $arrayElemAt: [ "$access_times", 0 ] },
                       prev: { $arrayElemAt: [ "$access_times", 0 ] },
                       sessions: []
                   },
                   in: {
                       $cond: [ { $gt: [ { $subtract: [ "$$this", "$$value.prev" ] }, FIVE_MINS ] },
                                { 
                                   first: "$$this", 
                                   prev: "$$this",
                                   sessions: { $concatArrays: [ "$$value.sessions" , 
                                                                [ { start: "$$value.first", end: "$$value.prev" } ] 
                                              ] } 
                                 },
                                 { 
                                    first: "$$value.first", 
                                    prev: "$$this", 
                                    sessions: "$$value.sessions" 
                                 }
                       ]
                   }
              }
          }
      }
  },
  { 
      $project: {
          _id: 0,
          account: "$_id",
          access_times: 1,
          sessions: { 
              $concatArrays: [ "$sessions.sessions", [ { start: "$sessions.first", end: "$sessions.prev" } ] ] 
          }
      } 
  }
] )

Вывод (с использованием опубликованных данных):

{
        "access_times" : [
                ISODate("2020-04-04T12:27:00Z"),
                ISODate("2020-04-04T12:30:21Z"),
                ISODate("2020-04-04T12:31:20Z"),
                ISODate("2020-04-04T12:40:20Z"),
                ISODate("2020-04-04T12:41:25Z"),
                ISODate("2020-04-04T12:42:30Z")
        ],
        "account" : "aaaa",
        "sessions" : [
                {
                        "start" : ISODate("2020-04-04T12:27:00Z"),
                        "end" : ISODate("2020-04-04T12:31:20Z")
                },
                {
                        "start" : ISODate("2020-04-04T12:40:20Z"),
                        "end" : ISODate("2020-04-04T12:42:30Z")
                }
        ]
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...