Giới thiệu
Khi dữ liệu ngày tháng được lưu dưới dạng String, bạn cần chuyển đổi sang kiểu Date (ISODate) để có thể query theo range, sort, và dùng các toán tử date. MongoDB shell cho phép dùng forEach để duyệt và cập nhật.
Ví dụ minh họa
1. Tạo collection với ShippingDate dạng String
> db.chuyenDoiNgay.insertOne({ "TenKhachHang": "Carol", "NgayGui": "2019-01-21" });
{ "acknowledged" : true, "insertedId" : ObjectId("5ca2071d66324ffac2a7dc60") }
> db.chuyenDoiNgay.insertOne({ "TenKhachHang": "Bob", "NgayGui": "2019-02-24" });
{ "acknowledged" : true, "insertedId" : ObjectId("5ca2073566324ffac2a7dc61") }
> db.chuyenDoiNgay.insertOne({ "TenKhachHang": "Chris", "NgayGui": "2019-04-01" });
{ "acknowledged" : true, "insertedId" : ObjectId("5ca2074266324ffac2a7dc62") }
2. Chuyển đổi String → ISODate với forEach + save()
> db.chuyenDoiNgay.find().forEach(function(doc) {
doc.NgayGui = ISODate(doc.NgayGui);
db.chuyenDoiNgay.save(doc);
});
3. Kết quả - Đã chuyển thành ISODate
> db.chuyenDoiNgay.find().pretty();
{ "_id" : ObjectId("5ca2071d66324ffac2a7dc60"), "TenKhachHang" : "Carol", "NgayGui" : ISODate("2019-01-21T00:00:00Z") }
{ "_id" : ObjectId("5ca2073566324ffac2a7dc61"), "TenKhachHang" : "Bob", "NgayGui" : ISODate("2019-02-24T00:00:00Z") }
{ "_id" : ObjectId("5ca2074266324ffac2a7dc62"), "TenKhachHang" : "Chris", "NgayGui" : ISODate("2019-04-01T00:00:00Z") }
Phương pháp hiện đại: Aggregation Pipeline Update (MongoDB 4.2+)
Hiệu quả hơn, atomic, không cần vòng lặp:
db.chuyenDoiNgay.updateMany(
{ NgayGui: { $type: "string" } }, // Chỉ doc có String
[
{ $set: { NgayGui: { $dateFromString: { dateString: "$NgayGui" } } } }
]
);
Các hàm chuyển đổi date trong Aggregation (MongoDB 4.0+)
| Toán tử | Mô tả | Ví dụ |
|---|---|---|
$dateFromString | Chuyển string → Date | { $dateFromString: { dateString: "$NgayGui" } } |
$dateFromParts | Tạo Date từ các thành phần | { $dateFromParts: { year: 2019, month: 1, day: 21 } } |
$toDate | Chuyển đổi tự động (string, long, date) | { $toDate: "$NgayGui" } |
$dateToString | Chuyển Date → String (format) | { $dateToString: { date: "$NgayGui", format: "%Y-%m-%d" } } |
Xử lý các định dạng string phức tạp
// Với timezone và format tùy chỉnh
db.collection.updateMany(
{ ngay: { $type: "string" } },
[
{ $set: {
ngay: {
$dateFromString: {
dateString: "$ngay",
format: "%Y-%m-%d %H:%M:%S", // Tùy chỉnh format
timezone: "Asia/Ho_Chi_Minh" // Múi giờ
}
}
} }
]
);
Lưu ý quan trọng
- Backup trước khi chạy updateMany trên production
- Test trên tập nhỏ hoặc staging trước
save()thay thế toàn bộ document - cẩn thận với concurrent modification- Aggregation update (4.2+) an toàn hơn, atomic per document
- Sau khi chuyển, hãy tạo index trên trường Date để query nhanh
Validation: Kiểm tra đã chuyển thành công
// Đếm doc còn String
db.collection.countDocuments({ ngay: { $type: "string" } });
// Đếm doc đã là Date
db.collection.countDocuments({ ngay: { $type: "date" } });