Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> MongoDB

Cách giới hạn phần tử mảng con (sub-array) trong MongoDB

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ápKế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 $arrayElemAt trong aggregation