Giới thiệu
Để giới hạn số lượng phần tử trả về từ một mảng (array) trong document, MongoDB cung cấp toán tử projection $slice. Điều này hữu ích khi mảng lớn nhưng bạn chỉ cần một phần.
Cú pháp
// Lấy N phần tử đầu
db.collection.find({}, { tenMang: { $slice: N } });
// Lấy N phần tử cuối
db.collection.find({}, { tenMang: { $slice: -N } });
// Bỏ qua skip phần tử đầu, lấy limit phần tử tiếp theo
db.collection.find({}, { tenMang: { $slice: [ skip, limit ] } });
Ví dụ minh họa: Lấy 10 phần tử cuối của mảng điểm game
1. Tạo document với mảng lớn
> db.gioiHanMang.insertOne({
_id: 101,
"TenNguoiChoi": "Bob",
"ThongTinNguoiChoi": { "Tuoi": 23, "LaSinhVien": true },
"DiemGame": [234, 5767, 58, 67, 78, 90, 1002, 576, 68, 45, 23, 45, 678, 89, 78]
});
{ "acknowledged" : true, "insertedId" : 101 }
2. Lấy 10 điểm cuối cùng ($slice: -10)
> db.gioiHanMang.find({}, { TenNguoiChoi: 1, ThongTinNguoiChoi: 1, DiemGame: { $slice: -10 } }).pretty();
3. Kết quả
{
"_id" : 101,
"TenNguoiChoi" : "Bob",
"ThongTinNguoiChoi" : { "Tuoi" : 23, "LaSinhVien" : true },
"DiemGame" : [ 90, 1002, 576, 68, 45, 23, 45, 678, 89, 78 ]
}
Mảng gốc 15 phần tử, chỉ trả về 10 phần tử cuối.
Trong Aggregation Pipeline
db.collection.aggregate([
{ $project: {
TenNguoiChoi: 1,
DiemGameCuoi: { $slice: [ "$DiemGame", -10 ] } // $slice trong aggregation
} }
]);
Bảng tóm tắt $slice
| Cú pháp | Kết quả với mảng [1,2,3,4,5,6,7,8,9,10] |
|---|---|
{ $slice: 3 } | [1, 2, 3] (3 đầu) |
{ $slice: -3 } | [8, 9, 10] (3 cuối) |
{ $slice: [2, 3] } | [3, 4, 5] (bỏ 2, lấy 3) |
{ $slice: [-3, 2] } | [8, 9] (từ 3 cuối, lấy 2) |
Kết hợp với các projection khác
db.collection.find(
{ filter }, // Query filter
{
_id: 0, // Ẩn _id
tenTruong: 1, // Include field
mangLon: { $slice: 5 }, // 5 phần tử đầu
mangKhac: { $slice: -3 } // 3 phần tử cuối
}
);
Lưu ý
- $slice trong
find()chỉ dùng cho **projection** (trường thứ 2) - Không thể dùng $slice trong query filter (trường thứ 1)
- Trong aggregation, $slice có ngữ pháp khác:
{ $slice: [ array, n ] }hoặc{ $slice: [ array, skip, limit ] } - Kết quả $slice luôn là **mảng** (da cả khi slice 1 phần tử)
- Để lấy giá trị đơn lẻ, dùng
$arrayElemAttrong aggregation