Как группировать данные по часам - PullRequest
3 голосов
/ 30 января 2020

Как получить данные подсчета, сгруппированные по часам в течение 24 часов, даже если данные отсутствуют, т. Е. Если IF 0 выберет 0

MonogDB 3,6

Ввод

[
  {
    "_id": ObjectId("5ccbb96706d1d47a4b2ced4b"),
    "date": "2019-05-03T10:39:53.108Z",
    "id": 166,
    "update_at": "2019-05-03T02:45:36.208Z",
    "type": "image"
  },
  {
    "_id": ObjectId("5ccbb96706d1d47a4b2ced4c"),
    "date": "2019-05-03T10:39:53.133Z",
    "id": 166,
    "update_at": "2019-05-03T02:45:36.208Z",
    "type": "image"
  },
  {
    "_id": ObjectId("5ccbb96706d1d47a4b2ced4d"),
    "date": "2019-05-03T10:39:53.180Z",
    "id": 166,
    "update_at": "2019-05-03T20:45:36.208Z",
    "type": "image"
  },
  {
    "_id": ObjectId("5ccbb96706d1d47a4b2ced7a"),
    "date": "2019-05-10T10:39:53.218Z",
    "id": 166,
    "update_at": "2019-12-04T10:45:36.208Z",
    "type": "image"
  },
  {
    "_id": ObjectId("5ccbb96706d1d47a4b2ced7b"),
    "date": "2019-05-03T10:39:53.108Z",
    "id": 166,
    "update_at": "2019-05-05T10:45:36.208Z",
    "type": "image"
  },
  {
    "_id": ObjectId("5ccbb96706d1d47a4b2cedae"),
    "date": "2019-05-03T10:39:53.133Z",
    "id": 166,
    "update_at": "2019-05-05T10:45:36.208Z",
    "type": "image"
  },
  {
    "_id": ObjectId("5ccbb96706d1d47a4b2cedad"),
    "date": "2019-05-03T10:39:53.180Z",
    "id": 166,
    "update_at": "2019-05-06T10:45:36.208Z",
    "type": "image"
  },
  {
    "_id": ObjectId("5ccbb96706d1d47a4b2cedab"),
    "date": "2019-05-10T10:39:53.218Z",
    "id": 166,
    "update_at": "2019-12-06T10:45:36.208Z",
    "type": "image"
  }
]

Реализация

db.collection.aggregate({
  $match: {
    update_at: {
      "$gte": "2019-05-03T00:00:00.0Z",
      "$lt": "2019-05-05T00:00:00.0Z"
    },
    id: {
      "$in": [
        166
      ]
    }
  }
},
{
  $group: {
    _id: {
      $substr: [
        "$update_at",
        11,
        2
      ]
    },
    count: {
      "$sum": 1
    }
  },

},
{
  $project: {
    _id: 0,
    hour: "$_id",
    count: "$count"
  }
},
{
  $sort: {
    hour: 1
  }
})

Фактический вывод :

{
    "count": 2,
    "hour": "02"
  },
  {
    "count": 1,
    "hour": "20"
  }

Мой код ожидания показывает данные о событиях за 24 часа имеет значение 0 или ноль и преобразует из примера «02» в «02 AM», «13» в «01 PM»:

Ожидаемый результат

  {
    "count": 0,
    "hour": "01" // 01 AM
  },
  {
    "count": 2,
    "hour": "02"
  },
  {
    "count": 0,
    "hour": "03"
  },
  {
    "count": 0,
    "hour": "04"
  },
  {
    "count": 0,
    "hour": "05"
  },
  {
    "count": 1,
    "hour": "20" // to 08 pm
  }

Ответы [ 5 ]

0 голосов
/ 31 января 2020

Попробуйте это решение:

Объяснение

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

Затем мы добавляем дополнительное поле hour для создания временного интервала (если у вас был v4.x, есть лучшее решение ).

Мы выравниваем поле hour (создадим новые документы) и разделяем первые 2 цифры, чтобы соответствовать count, и разделяем последние 2 цифры, чтобы задать периоды AM / PM.


db.collection.aggregate([
  {
    $match: {
      update_at: {
        "$gte": "2019-05-03T00:00:00.0Z",
        "$lt": "2019-05-05T00:00:00.0Z"
      },
      id: {
        "$in": [
          166
        ]
      }
    }
  },
  {
    $group: {
      _id: {
        $substr: [
          "$update_at",
          11,
          2
        ]
      },
      count: {
        "$sum": 1
      }
    }
  },
  {
    $addFields: {
      hour: [
        "0000",
        "0101",
        "0202",
        "0303",
        "0404",
        "0505",
        "0606",
        "0707",
        "0808",
        "0909",
        "1010",
        "1111",
        "1212",
        "1301",
        "1402",
        "1503",
        "1604",
        "1705",
        "1806",
        "1907",
        "2008",
        "2109",
        "2210",
        "2311"
      ]
    }
  },
  {
    $unwind: "$hour"
  },
  {
    $project: {
      _id: 0,
      hour: 1,
      count: {
        $cond: [
          {
            $eq: [
              {
                $substr: [
                  "$hour",
                  0,
                  2
                ]
              },
              "$_id"
            ]
          },
          "$count",
          0
        ]
      }
    }
  },
  {
    $group: {
      _id: "$hour",
      count: {
        "$sum": "$count"
      }
    }
  },
  {
    $sort: {
      _id: 1
    }
  },
  {
    $project: {
      _id: 0,
      hour: {
        $concat: [
          {
            $substr: [
              "$_id",
              2,
              2
            ]
          },
          {
            $cond: [
              {
                $gt: [
                  {
                    $substr: [
                      "$_id",
                      0,
                      2
                    ]
                  },
                  "12"
                ]
              },
              " PM",
              " AM"
            ]
          }
        ]
      },
      count: "$count"
    }
  }
])

MongoPlayground

0 голосов
/ 30 января 2020

Если вы хотите вывести в формате индийского времени. тогда ниже код работает!

    const query = [
    {
        $match: {
            update_at: {
                "$gte": ISODate("2019-05-03T00:00:00.0Z"),
                "$lt": ISODate("2019-05-05T00:00:00.0Z")
            },
            id: {
                "$in": [
                    166
                ]
            }
        }
    },
    {
        $project: {
            "h": { "$hour": { date: "$update_at", timezone: "+0530" } },
        }
    },
    {
        $group:
        {
            _id: { $hour: "$h" },
            count: { $sum: 1 }
        }
    }
];
0 голосов
/ 30 января 2020

Нет решения "волхвов c", вам придется жестко закодировать его в агрегацию:

Вот пример использования синтаксиса Mon go v3.2 + с некоторой картой $ и $ filter magi c:

db.collection.aggregate([
    {
        $match: {
            update_at: {
                "$gte": "2019-05-03T00:00:00.0Z",
                "$lt": "2019-05-05T00:00:00.0Z"
            },
            id: {"$in": [166]}
        }
    },
    {
        $group: {
            _id: {$substr: ["$update_at", 11, 2]},
            count: {"$sum": 1}
        }
    },
    {
        $group: {
            _id: null,
            hours: {$push: {hour: "$_id", count: "$count"}}
        }
    },
    {
        $addFields: {
            hours: {
                $map: {
                    input: {
                        $concatArrays: [
                            "$hours",
                            {
                                $map: {
                                    input: {
                                        $filter: {
                                            input: ["00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23"],
                                            as: "missingHour",
                                            cond: {
                                                $not: {
                                                    $in: [
                                                        "$$missingHour",
                                                        {
                                                            $map: {
                                                                input: "$hours",
                                                                as: "hourObj",
                                                                in: "$$hourObj.hour"
                                                            }
                                                        }
                                                    ]
                                                }
                                            }
                                        }
                                    },
                                    as: "missingHour",
                                    in: {hour: "$$missingHour", count: 0}
                                }
                            }
                        ]
                    },
                    as: "hourObject",
                    in: {
                        count: "$$hourObject.count",
                        hour: {
                            $cond: [
                                {$eq: [{$substr: ["$$hourObject.hour", 0, 1]}, "0"]},
                                {$concat: ["$$hourObject.hour", " AM"]},
                                {
                                    $concat: [{
                                        $switch: {
                                            branches: [
                                                {case: {$eq: ["$$hourObject.hour", "13"]}, then: "1"},
                                                {case: {$eq: ["$$hourObject.hour", "14"]}, then: "2"},
                                                {case: {$eq: ["$$hourObject.hour", "15"]}, then: "3"},
                                                {case: {$eq: ["$$hourObject.hour", "16"]}, then: "4"},
                                                {case: {$eq: ["$$hourObject.hour", "17"]}, then: "5"},
                                                {case: {$eq: ["$$hourObject.hour", "18"]}, then: "6"},
                                                {case: {$eq: ["$$hourObject.hour", "19"]}, then: "7"},
                                                {case: {$eq: ["$$hourObject.hour", "20"]}, then: "8"},
                                                {case: {$eq: ["$$hourObject.hour", "21"]}, then: "9"},
                                                {case: {$eq: ["$$hourObject.hour", "22"]}, then: "10"},
                                                {case: {$eq: ["$$hourObject.hour", "23"]}, then: "11"},
                                            ],
                                            default: "None"
                                        }
                                    }, " PM"]
                                }
                            ]
                        }
                    }
                }
            }
        }
    },
    {
        $unwind: "$hours"
    },
    {
        $project: {
            _id: 0,
            hour: "$hours.hour",
            count: "$hours.count"
        }
    },
    {
        $sort: {
            hour: 1
        }
    }
]);

Краткое объяснение этапа $addFields: сначала мы добавляем пропущенные часы, затем объединяем два массива (из первоначальных найденных часов и «новых» пропущенных часов), наконец, мы конвертируем в требуемый вывод («01» в «01 AM»).

Если вы используете Mon go v4 + Я рекомендую изменить $group _id этап, чтобы использовать $ dateFromString в качестве более согласованного.

_id: {$hour: {$dateFromString: {dateString: "$update_at"}}}

Если вы это сделаете, вам придется обновить Секции $filter и $map для использования чисел, а не строк, и, в конечном итоге, $ toString для приведения в нужный вам формат, отсюда и требование v4 +.

0 голосов
/ 30 января 2020

Вы должны хранить значения даты как Date объекты вместо строк. Я бы сделал форматирование так:

db.collection.aggregate(
   [
      { $match: { ... } },
      {
         $group: {
            _id: { h: { $hour: "$update_at" } },
            count: { $sum: 1 }
         }
      },
      {
         $project: {
            _id: 0,
            hour: {
               $switch: {
                  branches: [
                     { case: { $lt: ["$_id.h", 10] }, then: { $concat: ["0", { $toString: "$_id.h" }, " AM"] } },
                     { case: { $lt: ["$_id.h", 13] }, then: { $concat: [{ $toString: "$_id.h" }, " AM"] } },
                     { case: { $lt: ["$_id.h", 22] }, then: { $concat: ["0", { $toString: { $subtract: ["$_id.h", 12] } }, " PM"] } },
                     { case: { $lt: ["$_id.h", 24] }, then: { $concat: [{ $toString: { $subtract: ["$_id.h", 12] } }, " PM"] } }
                  ]
               }
            },
            hour24: "$_id.h",
            count: 1
         }
      },
      { $sort: { hour24: 1 } }
   ])

Как неамериканец, я не знаком с правилами AM / PM, особенно для полуночи и полудня, но я думаю, вы понимаете принцип.

0 голосов
/ 30 января 2020

Вот запрос, который вы можете проверить, для MongoDB 4.0 +

я буду улучшать запрос и обновлять

const query = [{
    $match: {
        update_at: {
            "$gte": ISODate("2019-05-03T00:00:00.0Z"),
            "$lt": ISODate("2019-05-05T00:00:00.0Z")
        },
        id: {
            "$in": [
                166
            ]
        }
    }
},
{
    $group: {
        _id: { $hour: "$update_at" },
        count: {
            "$sum": 1
        }
    },

},

{
    $addFields: {
        hourStr: { $toString: { $cond: { if: { $gte: ["$_id", 12] }, then: { $subtract: [12, { $mod: [24, '$_id'] }] }, else: "$_id" } } },
    }
},
{
    $project: {
        formated: { $concat: ["$hourStr", { $cond: { if: { $gt: ["$_id", 12] }, then: " PM", else: " AM" } }] },
        count: "$count",
        hour: 1,
    }
}]
...