Để xóa các phần tử trong mảng **không thỏa mãn** điều kiện nhất định (logic: giữ lại phần tử thỏa, xóa phần tử không thỏa), bạn dùng $pull kết hợp toán tử $ne (not equal). Lưu ý: $pull xóa phần tử **khớp điều kiện**, nên điều kiện phải là "phần tử KHÔNG mong muốn".
1. Tạo dữ liệu: Mảng details chứa object có trường isMarried (boolean/string)
> db.demo410.insertOne({
details: [
{ isMarried: false },
{ isMarried: true },
{ isMarried: false },
{ isMarried: "Chris" } // Giá trị lạ (string)
]
});
2. Xem dữ liệu
> db.demo410.find();
Kết quả: 4 phần tử trong details.
3. Xóa tất cả phần tử KHÔNG có isMarried = true (giữ lại chỉ isMarried: true)
> db.demo410.updateMany(
{ "details": { $elemMatch: { "isMarried": { $ne: true } } } },
{ $pull: { "details": { "isMarried": { $ne: true } } } }
);
{ "acknowledged": true, "matchedCount": 1, "modifiedCount": 1 }
Giải thích logic:
- Filter
{ $elemMatch: { isMarried: { $ne: true } } }: Tìm tài liệu **có ít nhất 1 phần tử** có isMarried ≠ true (để updateMany chỉ chạy trên doc cần sửa). - Update
$pull: { details: { isMarried: { $ne: true } } }: Xóa **tất cả** phần tử trong mảng details mà isMarried ≠ true.
4. Kết quả: Chỉ còn phần tử isMarried: true
> db.demo410.find();
Kết quả:
{ "_id": ObjectId("..."), "details": [ { "isMarried": true } ] }
Lưu ý: $elemMatch trong filter ở đây chỉ để tối ưu (chỉ update doc có phần tử cần xóa). Nếu bỏ filter, updateMany({}, ...) cũng chạy đúng nhưng quét toàn collection.