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

Xóa phần tử thứ N (n-th element) của mảng trong MongoDB

MongoDB không có toán tử xóa trực tiếp theo chỉ số (index) của mảng. Cách phổ biến: dùng $unset đặt phần tử thành null theo vị trí, sau đó $pull loại bỏ các null.

Cú pháp (2 bước)

// Bước 1: Unset phần tử tại index N (0-based)
db.collection.update({}, { $unset: { "tênMảng.N": 1 } });

// Bước 2: Pull các null còn sót lại
db.collection.update({}, { $pull: { "tênMảng": null } });

Ví dụ minh họa

Tạo collection getNThElementDemo:

> db.getNThElementDemo.insertOne({ "UserName": "John", "UserAge": 23, "ListOfFriends": ["Carol", "Sam", "Mike", "Bob"] });
> db.getNThElementDemo.insertOne({ "UserName": "David", "UserAge": 21, "ListOfFriends": ["Chris", "Robert"] });

Hiển thị (ListOfFriends của John: index 0=Carol, 1=Sam, 2=Mike, 3=Bob):

> db.getNThElementDemo.find().pretty();

Kết quả:

{ "_id" : ..., "UserName" : "John", "UserAge" : 23, "ListOfFriends" : [ "Carol", "Sam", "Mike", "Bob" ] }
{ "_id" : ..., "UserName" : "David", "UserAge" : 21, "ListOfFriends" : [ "Chris", "Robert" ] }

Xóa phần tử index 2 (Mike) của John

> db.getNThElementDemo.update({}, { $unset: { "ListOfFriends.2": 1 } });
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.getNThElementDemo.update({}, { $pull: { "ListOfFriends": null } });
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

Lưu ý: update({}, ...) không có filter sẽ cập nhật **document đầu tiên** khớp (thường là John). Trong production, hãy thêm filter cụ thể (ví dụ: { UserName: "John" }).

Kiểm tra kết quả:

> db.getNThElementDemo.find().pretty();

Kết quả:

{ "_id" : ..., "UserName" : "John", "UserAge" : 23, "ListOfFriends" : [ "Carol", "Sam", "Bob" ] }
{ "_id" : ..., "UserName" : "David", "UserAge" : 21, "ListOfFriends" : [ "Chris", "Robert" ] }

Phần tử "Mike" (index 2) đã bị xóa, mảng tự co lại.

Cách khác: Aggregation Pipeline Update (MongoDB 4.2+)

db.getNThElementDemo.updateOne(
    { UserName: "John" },
    [{ $set: { ListOfFriends: { $concatArrays: [ { $slice: ["$ListOfFriends", 2] }, { $slice: ["$ListOfFriends", 3, { $size: "$ListOfFriends" }] } ] } } }]
);

Cách này phức tạp hơn nhưng atomic (single operation).

Lưu ý quan trọng

  • Index mảng **0-based** (phần tử đầu = 0).
  • Nếu index vượt quá độ dài mảng, $unset không báo lỗi nhưng cũng không làm gì.
  • $pull: { arr: null } sẽ xóa **TẤT CẢ** null trong mảng (cẩn thận nếu mảng có null hợp lệ).
  • Để xóa theo giá trị (không theo vị trí): $pull: { ListOfFriends: "Mike" }.