Группа по методу Timestamp с базой агрегации в MongoDB

У меня есть следующий массив объектов из моего запроса MongoDB, чтобы получить статистику по времени:

[ { _id: { year: 2014, dayOfYear: 128, hour: 9 }, count: 2, avg: 0.12455, min: 0.1245, max: 0.1246, gv: 7.98954654895666, bv: 0.9950000000000001 }, { _id: { year: 2014, dayOfYear: 134, hour: 14 }, count: 8, avg: 0.12217854, min: 0.1212, max: 0.12345678, gv: 25.869999999999997, bv: 3.1652450614477337 }, { _id: { year: 2014, dayOfYear:126, hour: 19 }, count: 3, avg: 0.11234099999999998, min: 0.112341, max: 0.112341, gv: 29.849999999999998, bv: 3.3533788500000004 }
]

Я хочу в основном преобразовать объект _id в временную метку unix с помощью момента. Js Я просто не могу найти правильную функцию подчеркивания для итерации объектов, получения идентификационных данных и повторного создания массива.

В этом процессе я мог бы просто сделать moment(). Year ('2014'). Format ('Z').

желаемый результат:

{ unixtime: 1400599394, count: 3, avg: 0.11234099999999998, min: 0.112341, max: 0.112341, gv: 29.849999999999998, bv: 3.3533788500000004
}
1 ответ

Я знаю, что вы просили, как это сделать с обещаниями, но я просто беру на себя удар, основанный на наименовании полей под _id что это фактически выводится из структуры агрегации, и поэтому есть другой способ сделать это,

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

Кажется, это группировка "в час" в течение каждого дня, поэтому давайте применим математику даты, чтобы изменить это значение временной отметки. Поэтому вместо того, чтобы использовать операторы даты, чтобы разбить дату в ключевой строке конвейера $group, сделайте это вместо этого:

{ "$group": { "_id": { "$subtract": [ { "$subtract": [ "$created", new Date("1970-01-01") ] }, { "$mod": [ { "$subtract": [ "$created", new Date("1970-01-01") ] }, 1000*60*60 ]} ] }
}}

Конечно, укажите все другие вещи, которые у вас есть в конвейере агрегации (которые не заданы в этом вопросе), но в результате фактическое значение временной метки эпохи усекается до часа дня с вашего исходного поля даты, которое называется "создано" ".

Чтобы разбить части этого, рассмотрим этот объект даты:

var date = new Date()
date.valueOf()
1400639001169

Итак, вы видите представление временной метки эпохи, извлеченное из объекта даты. С точки зрения математики получение этого значения с помощью .valueOf() в точности совпадает с:

date - new Date("1970-01-01")
1400639001169

Который дает вам секунды (или миллисекунды в этом случае), прошедшие с "1970-01-01", и это именно то, что имеет эпоха. Для этого мы можем получить миллисекунды, прошедшие через 1 час в качестве части этой даты, получив модуль:

date % ( 1000*60*60 )
1401169

Таким образом, с 1000 миллисекунд в секунду, 60 секунд в минуту и 60 минут в час, мы получаем этот результат. Все, что осталось сейчас, это вычесть это значение из исходного значения даты:

date - date % ( 1000*60*60 )
1400637600000

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

Initial: Wed, 21 May 2014 02:23:21 GMT Converted: Wed, 21 May 2014 02:00:00 GMT

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

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

licensed under cc by-sa 3.0 with attribution.