Để lọc tài liệu theo giờ (hour) của trường datetime, MongoDB Aggregation Framework cung cấp toán tử $hour trích xuất giờ từ Date/ISODate, kết hợp với $match và $in.
Tạo dữ liệu mẫu
> db.mongoDbSearchForHoursDemo.insertOne({"CustomerName":"Larry","OrderDatetime":new ISODate("2019-01-31 09:45:50")});
{ "acknowledged" : true, "insertedId" : ObjectId("5cd6e8a86d78f205348bc62a") }
> db.mongoDbSearchForHoursDemo.insertOne({"CustomerName":"Larry","OrderDatetime":new ISODate("2019-02-21 01:10:01")});
{ "acknowledged" : true, "insertedId" : ObjectId("5cd6e8b86d78f205348bc62b") }
> db.mongoDbSearchForHoursDemo.insertOne({"CustomerName":"Larry","OrderDatetime":new ISODate("2019-04-01 04:10:11")});
{ "acknowledged" : true, "insertedId" : ObjectId("5cd6e8e26d78f205348bc62c") }
> db.mongoDbSearchForHoursDemo.insertOne({"CustomerName":"Larry","OrderDatetime":new ISODate("2019-05-11 08:53:01")});
{ "acknowledged" : true, "insertedId" : ObjectId("5cd6e8f26d78f205348bc62d") }
Xem dữ liệu
> db.mongoDbSearchForHoursDemo.find().pretty();
Tìm bản ghi vào giờ 1 AM và 8 AM
> db.mongoDbSearchForHoursDemo.aggregate([ {$project: {SpecificHours: {$hour: "$OrderDatetime"}}}, {$match: {SpecificHours: {$in: [8, 1]}}} ]);Kết quả
Giải thích
$hour: "$OrderDatetime": Trích xuất giờ (0-23) từ ISODate (theo UTC)$project: Tạo trường mớiSpecificHourschứa giá trị giờ$matchvới$in: [8, 1]: Lọc giữ lại giờ 8 hoặc 1- Kết quả chỉ chứa _id và SpecificHours (do $project)
Giữ nguyên tài liệu gốc
db.mongoDbSearchForHoursDemo.aggregate([
{$addFields: {Hour: {$hour: "$OrderDatetime"}}},
{$match: {Hour: {$in: [8, 1]}}},
{$project: {Hour: 0}} // Ẩn trường Hour khỏi kết quả
]);
Các toán tử ngày tháng liên quan
| Toán tử | Trả về | Ví dụ |
|---|---|---|
$year | Năm (4 chữ số) | 2019 |
$month | Tháng (1-12) | 5 |
$dayOfMonth | Ngày trong tháng (1-31) | 11 |
$hour | Giờ (0-23) | 8 |
$minute | Phút (0-59) | 53 |
$second | Giây (0-59) | 1 |
$dayOfWeek | Thứ (1=CN, 7=Thứ 7) | 7 |
$week | Tuần trong năm (0-53) | 19 |
Lưu ý múi giờ (Timezone)
- MongoDB lưu Date theo UTC
$hourtrả về giờ UTC- Để chuyển múi giờ: dùng
$dateToStringvớitimezone(MongoDB 3.6+) - Ví dụ giờ Việt Nam (UTC+7):
{$dateToString: {date: "$OrderDatetime", format: "%H", timezone: "+07:00"}}
Tối ưu hiệu năng
Aggregation với $hour không sử dụng index trên trường Date. Với dữ liệu lớn, cân nhắc:
- Lưu thêm trường
Hourriêng khi insert (denormalization) - Tạo index trên trường Hour
- Hoặc query range:
{OrderDatetime: {$gte: startOfHour, $lt: endOfHour}}