Giới thiệu
Có nhiều cách để lấy phần tử đầu tiên của một mảng trong MongoDB. Bài viết này giới thiệu 2 phương pháp phổ biến: dùng Aggregation Pipeline ($unwind + $group + $first) và dùng toán tử $slice trong find().
Phương pháp 1: Aggregation Pipeline
1. Tạo dữ liệu mẫu
> db.layPhanTuDau.insertOne({"TenSinhVien":"John","MonHoc":["MongoDB","Python","MySQL"]});
{ "acknowledged" : true, "insertedId" : ObjectId("5c9c41292d6669774125244e") }
> db.layPhanTuDau.insertOne({"TenSinhVien":"Chris","MonHoc":["Java","C"]});
{ "acknowledged" : true, "insertedId" : ObjectId("5c9c413f2d6669774125244f") }
> db.layPhanTuDau.insertOne({"TenSinhVien":"Robert","MonHoc":["C++","Ruby"]});
{ "acknowledged" : true, "insertedId" : ObjectId("5c9c41532d66697741252450") }
2. Pipeline aggregation
> db.layPhanTuDau.aggregate([
{ $unwind: "$MonHoc" },
{ $group: { "_id": "$_id", "PhanTuDau": { $first: "$MonHoc" } } },
{ $project: { "_id": 0, "PhanTuDau": 1 } }
]);
3. Kết quả
{ "PhanTuDau" : "MongoDB" }
{ "PhanTuDau" : "Java" }
{ "PhanTuDau" : "C++" }
Phương pháp 2: Sử dụng $slice trong find() (Đơn giản hơn)
> db.layPhanTuDau.find({}, { "MonHoc": { $slice: 1 } });
Kết quả
{ "_id" : ObjectId("..."), "TenSinhVien" : "John", "MonHoc" : [ "MongoDB" ] }
{ "_id" : ObjectId("..."), "TenSinhVien" : "Chris", "MonHoc" : [ "Java" ] }
{ "_id" : ObjectId("..."), "TenSinhVien" : "Robert", "MonHoc" : [ "C++" ] }
So sánh 2 phương pháp
| Tiêu chí | Aggregation ($unwind) | find() + $slice |
|---|---|---|
| Độ phức tạp | Cao | Thấp |
| Hiệu suất | Chậm hơn (unwind tạo nhiều doc) | Nhanh hơn |
| Linh hoạt | Cao (có thể xử lý phức tạp) | Chỉ lấy subset mảng |
| Trả về | Chỉ giá trị phần tử đầu | Vẫn giữ cấu trúc document |
Khuyến nghị
Sử dụng $slice trong find() cho trường hợp đơn giản chỉ cần lấy N phần tử đầu/cuối. Dùng aggregation khi cần xử lý phức tạp hơn (lọc, biến đổi, join...).