Để lấy phần tử đầu tiên của mảng trong projection, sử dụng $slice kết hợp điều kiện $gte.
Tạo collection điểm số
> db.demo640.insertOne({Name:"John", "Scores":[80,90,75]});
> db.demo640.insertOne({Name:"Chris", "Scores":[85,70,89]});
Hiển thị dữ liệu gốc
> db.demo640.find();
Kết quả:
{
"Name" : "John", "Scores" : [ 80, 90, 75 ]
}
{
"Name" : "Chris", "Scores" : [ 85, 70, 89 ]
}
Projection lấy phần tử đầu tiên của mảng Scores (điều kiện Scores >= 85)
> db.demo640.find({Scores: {$gte: 85}}, { "Scores": { $slice: 1 } });
Kết quả:
{
"_id" : ObjectId("5e9c2eb86c954c74be91e6e0"),
"Name" : "John", "Scores" : [ 80 ]
}
{
"_id" : ObjectId("5e9c2ece6c954c74be91e6e1"),
"Name" : "Chris", "Scores" : [ 85 ]
}
Giải thích:
- Điều kiện
{Scores: {$gte: 85}}: Tìm document có **ít nhất một** phần tử trong mảng Scores >= 85 - Projection
{ "Scores": { $slice: 1 } }: Chỉ lấy **1 phần tử đầu tiên** của mảng Scores (index 0) - John: Scores [80,90,75] → có 90 >= 85 → khớp → lấy phần tử đầu [80]
- Chris: Scores [85,70,89] → có 85 >= 85 → khớp → lấy phần tử đầu [85]
Các dạng $slice khác:
{$slice: n}: Lấy n phần tử đầu (n > 0){$slice: -n}: Lấy n phần tử cuối (n > 0){$slice: [skip, limit]}: Bỏ qua skip phần tử, lấy limit phần tử
Lưu ý: $slice trong find() projection khác với $slice trong aggregate (dùng $arrayElemAt hoặc $slice operator).