Для того, чтобы просто получить записи на текущий день, вам по-прежнему необходимо передать диапазон дат, представляющий начало дня и конец диапазона, который нужно искать. Предполагая, что вы реализовали это в своем классе с DateTimeField тем MongoDB будет использовать BSON date тип, который совместит с операторами агрегирования даты:
Record._get_collection().Aggregate([
{ "$match": {
"system_id": system.id,
"utc_timestamp": {
"$gte": datetime.datetime(2014,9,6)
"$lt": datetime.datetime(2014,9,7)
}
}},
{ "$group": {
"_id": { "$dayOfYear": "$utc_timestamp" }
....
На том $group
уровне эти операторы, как правило, имеет смысл использовать при объединении значений над более широкий диапазон, чем один день или иначе, через час или минуту в течение дня. В противном случае, поскольку даты уже выбраны, все это текущий день, и любой ключ агрегирования для другого поля или значение Null
по существу является агрегирующим для этого дня.
Если вместо того, чтобы с помощью «метки времени» вы на самом деле число, представляющее секунды с начала эпохи (тип BSON фактически внутренне использует миллисекунды с начала эпохи), то вы можете построить свой запрос так:
Record._get_collection().Aggregate([
{ "$match": {
"system_id": system.id,
"utc_timestamp": {
"$gte": (datetime.datetime(2014,9,6)
- datetime.datetime(1970,1,1)).total_seconds()
"$lt": (datetime.datetime(2014,9,7)
- datetime.datetime(1970,1,1)).total_seconds()
}
}},
{ "$group": {
"_id": {
"$subtract": [
"$utc_timestamp",
{ "$mod": [
"$utc_timestamp",
60 * 60 * 24
]}
]
},
...
Или аналогично отрегулируйте для miliseconds, который является более распространенным форматом временной метки эпохи, умножая на 1000. Для группировки стандартной «математики даты» применяется округление совпадающих значений временной метки до текущего дня.
Наконец, MongoEngine поддерживает ComplexDateTimeField, который сохраняет микросекунды, обычно доступные в объектах datetime python. К сожалению, фактическое хранилище в MongoDB является «строкой» в этом случае, поэтому ни математические, ни общие операторы даты действительно недоступны. Но строка в формате YYYY,MM,DD,HH,MM,SS,NNNNNN
, который, по крайней мере «лексически» заказал, и поэтому может быть диапазон выбран и расчлененный с $substr
, чтобы агрегировать в день, или другой период:
Record._get_collection().Aggregate([
{ "$match": {
"system_id": system.id,
"utc_timestamp": {
"$gte": "2014,09,06", "$lt": "2014,09,07"
}
}},
{ "$group": {
"_id": { "$substr": [ "$utc_timestamp", 0, 10 ] }
...
Но если вы используете любая другая форма строки, тогда у вас будут проблемы, поскольку она вряд ли хорошо преобразуется для выбора соответствия или группировки ключей. В этом случае вам лучше всего преобразовать любые такие строки, чтобы использовать одну из вышеперечисленных форм, с очевидным преимуществом при использовании родного типа даты BSON, поскольку это наилучшая поддерживаемая форма.
Какой формат поля utc_timestamp? –