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

Truy vấn MongoDB: Tất cả phần tử mảng nhỏ hơn điều kiện

Để 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ĩaGhi chú
{Scores: {$not: {$gt: 45}}}Không có phần tử > 45Cá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ử ≥ 46Tương đương
{$where: "function() { return this.Scores.every(x => x <= 45); }"}JavaScript functionChậ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"