Để tìm tài liệu mà tất cả phần tử trong mảng đều thỏa mãn một điều kiện (ví dụ: tất cả điểm số < 45), MongoDB sử dụng toán tử $not kết hợp với $gt (hoặc $gte). Logic: "Không tồn tại phần tử nào > 45" ≡ "Tất cả phần tử ≤ 45".
Tạo dữ liệu mẫu
> db.arrayElementsNotGreaterThanDemo.insertOne({"Scores":[89,43,32,45]});
{ "acknowledged" : true, "insertedId" : ObjectId("5cd9e9f9b50a6c6dd317adb3") }
> db.arrayElementsNotGreaterThanDemo.insertOne({"Scores":[32,33,34,40]});
{ "acknowledged" : true, "insertedId" : ObjectId("5cd9ea13b50a6c6dd317adb4") }
> db.arrayElementsNotGreaterThanDemo.insertOne({"Scores":[45,56,66,69]});
{ "acknowledged" : true, "insertedId" : ObjectId("5cd9ea25b50a6c6dd317adb5") }
> db.arrayElementsNotGreaterThanDemo.insertOne({"Scores":[46,66,77,88]});
{ "acknowledged" : true, "insertedId" : ObjectId("5cd9ea3cb50a6c6dd317adb6") }
Xem dữ liệu
> db.arrayElementsNotGreaterThanDemo.find().pretty();
Truy vấn: Tất cả Scores ≤ 45
> db.arrayElementsNotGreaterThanDemo.find({Scores: {$not: {$gt: 45}}});Kết quả
Giải thích logic
{$gt: 45}: Khớp tài liệu có ít nhất một phần tử > 45$not: Phủ định → tài liệu KHÔNG CÓ phần tử nào > 45- Tức là: Tất cả phần tử ≤ 45
- Chỉ mảng [32,33,34,40] thỏa mãn
Các cách viết tương đương
| Cú pháp | Ý nghĩa | Ghi chú |
|---|---|---|
{Scores: {$not: {$gt: 45}}} | Không có phần tử > 45 | Cách gốc |
{Scores: {$lte: 45}} | Tất cả phần tử ≤ 45 | Đơn giản hơn, khuyên dùng |
{Scores: {$not: {$gte: 46}}} | Không có phần tử ≥ 46 | Tương đương |
{$where: "function() { return this.Scores.every(x => x <= 45); }"} | JavaScript function | Chậm, không dùng index |
⚠️ Lưu ý quan trọng về {$field: {$lte: value}}
Khi dùng {Scores: {$lte: 45}} trên trường mảng:
- MongoDB so khớp: Ít nhất một phần tử ≤ 45
- KHÔNG phải "tất cả phần tử ≤ 45"
- Ví dụ: [89, 43, 32, 45] SẼ KHỚP vì có 43, 32, 45 ≤ 45
Cách đúng cho "Tất cả phần tử thỏa mãn"
Cách 1: $not + $gt (như ví dụ)
{Scores: {$not: {$elemMatch: {$gt: 45}}}}
Cách 3: Aggregation với $allElementsTrue (MongoDB 3.6+)
db.arrayElementsNotGreaterThanDemo.aggregate([
{$match: {
$expr: {$allElementsTrue: {$map: {input: "$Scores", as: "s", in: {$lte: ["$$s", 45]}}}}
}}
]);
Ứng dụng thực tế
- Kiểm tra tất cả điểm số đạt yêu cầu (≤ ngưỡng cho phép)
- Validate dữ liệu: Tất cả mục trong đơn hàng đều có số lượng > 0
- Kiểm tra trạng thái: Tất cả task đều "completed"