Mongodb — получение различных значений по дате/времени в течение часа

#mongodb #distinct-values

Вопрос:

Если я хочу попросить уникальные ценности, я могу это сделать:

 db.getCollection('cars').distinct('deparutre_date')
 

Результаты:

 2021-05-03 15:59:15.530Z
2021-05-03 15:59:24.534Z
2021-05-03 15:59:33.537Z
2021-05-03 15:59:38.537Z
2021-05-03 15:59:40.536Z
2021-05-03 14:28:41.530Z
 

Тем не менее, я хочу получить различные значения по часам, поэтому выше должно быть показано что-то вроде этого:

 2021-05-03 15:00:00.000Z
2021-05-03 14:00:00.000Z
 

Как я могу этого достичь?

Ответ №1:

Запрос

  • сгруппировать по
    • год выпуска (1-12)
    • день в году(1-366)
    • время суток(0-23)
  • сохраняйте только 1 дату(в любом случае у всех будет один и тот же год/месяц/день/час).
  • проект по восстановлению даты с использованием полей, которые у нас уже есть, тех, которые мы использовали для группировки

*все эти операторы также имеют дополнительные timezone: <tzExpression>

Тестовый код здесь

 db.collection.aggregate([
  {
    "$group": {
      "_id": {
        "year": {
          "$year": "$date"
        },
        "day-of-year": {
          "$dayOfYear": "$date"
        },
        "hour": {
          "$hour": "$date"
        }
      },
      "date": {
        "$first": "$date"
      }
    }
  },
  {
    "$project": {
      "_id": 0,
      "date": {
        "$dateFromParts": {
          "year": "$_id.year",
          "day": "$_id.day-of-year",
          "hour": "$_id.hour"
        }
      }
    }
  }
])
 

Запрос 2
(более короткая версия >= MongoDB v5, как предложил Вернфрид Домшей в комментарии)

Тестовый код здесь

 db.collection.aggregate([
  {
    "$set": {
      truncatedOrderDate: {
        $dateTrunc: {
          date: "$date",
          unit: "hour",
          timezone: "America/Los_Angeles"
        }
      }
    }
  },
  {
    "$group": {
      "_id": "$truncatedOrderDate",
      
    }
  }
])
 

Комментарии:

1. Если вы используете MongoDB 5.0 или новее, вы можете использовать более короткие _id: { $dateTrunc: { date: "$date", unit: "hour" } }

2. @ Wernfried Domschei Не могли бы вы поделиться ответом, как бы вы это сделали с dateTrunc. У меня была некоторая борьба с этим. Спасибо!

3. я добавил одно $dateTrunc решение, но я думаю, что они оба делают одно и то же, если у вас есть пример, который не работает, опубликуйте данные, если сможете

4. вышеуказанные группы одного и того же года месяца дня часа, если вы хотите только по часам, игнорируя год/месяц/день, это еще проще сделать, из ваших выборочных данных я предположил, что вы также хотите год месяц день час.