0

Мой первый пост StackOverflow!Pentaho Report Designer MongoDB группировка по эпохе timestamps

У меня есть коллекция MongoDB под названием user_sessions - один документ выглядит следующим образом:

{ 
    "_id" : ObjectId("53e352bbed3e4af00d8b459a"), 
    "active_date" : 1407406779727, 
    "auth_token" : "WObDF9KO6n1V34lgjlFIoXoiEmOH9CM8", 
    "device_token" : "3474ac2d5aa9c7dc933bd4548c2dd6ea3d8a9592dad1c1a807c06ac2c8459205", 
    "device_type" : "1", 
    "end_time" : "", 
    "sessionid" : "", 
    "start_time" : 1407406779727, 
    "userid" : "53e352bbed3e4af00d8b4599" 
} 

Я пытаюсь создать отчет с помощью конструктора отчетов Pentaho в (5.1). я сумел вывести общее количество пользовательских сессий с этим запросом:

[ 
     { $group: { _id: null, count: { $sum: 1 } } } 
] 

, который отлично.

Однако, я хотел бы также показать количество сеансов по дате.

Когда я запускаю этот скрипт против этой коллекции (с помощью драйвера PHP Монго):

$connection = new Mongo("mongodb://$dbhost"); 
$c_us = $db->user_session; 
$cursor = $c_us->find(); 
foreach ($cursor as $document) { 
    echo "<br/>UserID: " . $document['userid'] . ", StartTime: "; 
    $epoch = $document['start_time']; 
    echo date('Y-m-d',$epoch/1000); 
} 

я получаю этот выход:

UserID: 53dfa1a7ed3e4aef0d8b456b, StartTime: 2014-08-05 
UserID: 53e075deed3e4af00d8b4570, StartTime: 2014-08-05 
UserID: 53e079c9ed3e4af00d8b4573, StartTime: 2014-08-05 
UserID: 53e07f8ded3e4aef0d8b4580, StartTime: 2014-08-05 
UserID: 53e081f9ed3e4aef0d8b4583, StartTime: 2014-08-05 
UserID: 53e352bbed3e4af00d8b4599, StartTime: 2014-08-07 
UserID: 53e9fb9eed3e4af00d8b45a3, StartTime: 2014-08-12 
UserID: 53f215f6ed3e4aef0d8b45a3, StartTime: 2014-08-19 
UserID: 53f3eeb7ed3e4aef0d8b45a7, StartTime: 2014-08-20 
UserID: 54083e94ed3e4af00d8b45b0, StartTime: 2014-09-04 
UserID: 5412cd29ed3e4aef0d8b45bc, StartTime: 2014-09-12 
UserID: 54175625ed3e4aef0d8b45c0, StartTime: 2014-09-16 
UserID: 54351b7ced3e4af00d8b45ff, StartTime: 2014-10-08 
UserID: 5444f1dced3e4a56718b45bb, StartTime: 2014-10-20 
UserID: 54475d48ed3e4af00d8b4628, StartTime: 2014-10-22 
UserID: 5449cc77ed3e4a79638b4592, StartTime: 2014-10-24 
UserID: 53e3c875ed3e4af00d8b459d, StartTime: 2014-10-24 
UserID: 544f6bb7ed3e4af00d8b464a, StartTime: 2014-10-28 
UserID: 544de95aed3e4a56718b45f2, StartTime: 2014-10-31 
UserID: 545b125c4a4ddd30048b4567, StartTime: 2014-11-06 

Fantastic!

Но как я могу сделать подсчет сессий по дате (и месяцу/дате)?

Так выше, мне нужны отчеты, как это:

2014-08-05 5 
2014-08-07 1 
. 
. 
. 
2014-10-24 2 

и т.д.

и

Month/Year  Count 
Aug 2014  9 
Sep 2014  3 
Oct 2014  7 
Nov 2014  1 

Учитывая user_session схемы, как я могу преобразовать время эпоха в start_time к Месяц/Год и счет?

Мое исследование ключевых слов не дало мне ничего, что я могу попробовать.

Я в затруднении. Что я должен вводить в качестве поискового запроса? Может ли кто-нибудь дать мне несколько указателей?

Я был бы очень признателен.

Благодаря

Брэд

+0

Извините, что я не очень хорошо знаком с пентахом или PHP, но у MongoDB есть отличные агрегаторы даты, которые вы можете использовать, они описаны здесь: http://docs.mongodb.org/manual/reference/operator/aggregation/# дата-операторы – ranman

+0

@ranman! Благодаря! Я пошел по ссылке $ month и оказался здесь [link] http://docs.mongodb.org/manual/reference/operator/aggregation/month/#exp._S_month [/ link], и я изменил свой пример, но получаю эту ошибку : ' ошибки ("Печать Трассировка стека") @: 0 () @ SRC/MONGO/Shell/utils.js: 37 ([объект Массив]) @ SRC/MONGO/Shell/collection.js: 866 @ (оболочки): 15 неперехваченного исключения: агрегат не удалось: { \t "ErrMsg": "исключение: не может преобразовать из типа BSON NumberDouble к дате", \t "код": 16006, \t "оК" : 0 } ' – bradzo

ответ

0

Просто для записи, Есть date aggregation operators вы можете использовать, чтобы анализировать вещи, как $year и $month и $dayOfMonth в группировке ключей для структуры агрегирования следующим образом:

db.collection.aggregate([ 
    { "$group": { 
     "_id": { 
      "year": { "$year": "$start_time" }, 
      "month": { "$month": "$start_time" }, 
      "day": { "$dayOfMonth": "$start_time" } 
     }, 
     "count": { "$sum": 1 } 
    }} 
]) 

Но если вам удобны значения «timestamp» эпохи, вы всегда можете использовать этот базовый матч tric к с «датой» объектами и «дата математикой» в целом, чтобы произвести эпоху метка время округляется до вашего требуемого значения:

db.collection.aggregate([ 
    { "$group": { 
     "_id": { 
      "$subtract": [ 
       { "$subtract": [ "$start_time", new Date("1970-01-01") ] }, 
       { "$mod": [ 
        { "$subtract": [ "$start_time", new Date("1970-01-01") ] }, 
        1000 * 60 * 60 * 24 
       ]} 
      ] 
     }, 
     "count": { "$sum": 1 } 
    }} 
) 

С основным трюка есть в том, что, когда вы «вычесть» или делать другую аналогичную математику из один объект «даты» для другого, то результатом является «разность в миллисекундах» от объектов как целое число.В приведенном примере (1000 * 60 * 60 * 24) это равно один день во времени, а по модулю значение округляется до текущего дня.

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

Поскольку все входные данные для конвейера агрегации будут «сериализованы» при отправке, тогда все действительные «объекты данных» на любом заданном языке, которые поддерживаются драйвером, окажутся правильными входными значениями. Мы просто используем дату «эпохи» здесь, чтобы «преобразовать» значение объекта даты, присутствующее в коллекции, в целое число.

Это зависит от того, что вы предпочитаете как выход. Некоторые люди предпочитают «целочисленную» форму как легкий приведение к новому объекту «дата». Некоторые из них довольны отдельными частями поля, чтобы сделать это.

+0

Спасибо @ Neil - я попробовал свой первый код (заменив вашу «коллекцию» на «user_session») и получил эту ошибку: uncaught exception: aggregate failed: { \t "errmsg": "exception: невозможно преобразовать из типа BSON NumberDouble на сегодняшний день " \t "код": 16006, \t "оК": 0 } и ваш 2-й пример: неперехваченное исключение: агрегат не удалось: { \t "ERRMSG":" исключение: косяк $ вычитания aDate от NumberDouble ", \t" код ": 16556, \t" ok ": 0 } – bradzo

+0

@bradzo Это означает, что вы фактически не храните типы «даты», а только числовые значения времени. Используйте метод ** second ** без вычитаний из объектов даты, поскольку значения уже должны быть отметками времени «эпохи». И, возможно, не в миллисекундах, поэтому посмотрите на свои данные и, возможно, сбросьте множитель '1000'. –

+0

#Неплохо - когда я отбрасываю материал #subtract, я получаю то же, что и в своем первоначальном сообщении, - просто количество записей, то есть: 20. Я просто не знаю, как преобразовать эту временную метку времени (которая нуждается в чтобы быть/1000 в PHP-скрипте, чтобы дать мне правильную дату) в объект даты. Я читал, что это невозможно. Возможно, мне следует использовать скрипт Groovy (помните, что окончательный запрос будет выполняться сервером отчетов Pentaho) - Спасибо за вашу помощь. – bradzo

Смежные вопросы