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

Lọc document dựa trên mảng trong MongoDB với $elemMatch

Lọc document chứa phần tử mảng thỏa mãn điều kiện với $elemMatch

$elemMatch khớp document khi ít nhất một phần tử trong mảng thỏa mãn tất cả điều kiện chỉ định.

1. Dữ liệu: mảng details chứa object {Name, Marks}

> db.demo453.insertOne({ _id: 101, details: [{ Name: "David", Marks: 60 }, { Name: "Mike", Marks: 55 }] });
> db.demo453.insertOne({ _id: 102, details: [{ Name: "Bob", Marks: 80 }, { Name: "Sam", Marks: 78 }] });
> db.demo453.insertOne({ _id: 103, details: [{ Name: "Carol", Marks: 67 }, { Name: "John", Marks: 79 }] });

2. Tìm document có ít nhất 1 học sinh Marks >= 75

> db.demo453.find({
    details: { $elemMatch: { Marks: { $gte: 75 } } }
});

3. Kết quả

{ "_id": 102, "details": [{ "Name": "Bob", "Marks": 80 }, { "Name": "Sam", "Marks": 78 }] }
{ "_id": 103, "details": [{ "Name": "Carol", "Marks": 67 }, { "Name": "John", "Marks": 79 }] }

Giải thích

  • Doc 101: Max Marks = 60 → Không khớp
  • Doc 102: Có Bob (80) và Sam (78) → Khớp
  • Doc 103: Có John (79) → Khớp (dù Carol chỉ 67)

$elemMatch vs Dot Notation (quan trọng!)

// Dữ liệu: { scores: [ { subject: "Math", score: 80 }, { subject: "English", score: 90 } ] }

// TRUY VẤN 1: Dot notation (SAI cho nhiều điều kiện)
db.find({ "scores.subject": "Math", "scores.score": 90 });
// Khớp! Vì CÓ subject="Math" (phần tử 1) VÀ CÓ score=90 (phần tử 2) - KHÁC PHẦN TỬ

// TRUY VẤN 2: $elemMatch (ĐÚNG)
db.find({ scores: { $elemMatch: { subject: "Math", score: 90 } } });
// Không khớp - vì không có phần tử NÀO CẢ HAI: subject="Math" VÀ score=90

Khi nào bắt buộc dùng $elemMatch?

  • Lọc mảng object với 2+ điều kiện trên cùng một phần tử
  • Cần chính xác logic "AND trên cùng một object con"

Index cho $elemMatch

db.demo453.createIndex({ "details.Marks": 1 }); // Multikey index tự động
// Hoặc compound cho query phức tạp
db.demo453.createIndex({ "details.Name": 1, "details.Marks": 1 });