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

Cách dùng $elemMatch trên mảng cấp 1 (first-level array) trong MongoDB

Giới thiệu

Toán tử $elemMatch được thiết kế cho **mảng chứa object** (array of objects) để match nhiều điều kiện trên **cùng một element**. Đối với mảng cấp 1 chứa giá trị đơn giản (string, number), bạn **không cần** $elemMatch - chỉ dùng truy vấn trực tiếp hoặc $in.

Mảng cấp 1 giá trị đơn giản: Dùng $in hoặc truy vấn trực tiếp

Ví dụ: Kỹ năng kỹ thuật (mảng string)

> db.mangCap1.insertOne({ "TenSinhVien": "Chris", "KyNang": ["MongoDB", "MySQL", "SQL Server"] });
{ "acknowledged" : true, "insertedId" : ObjectId("5ca2360f66324ffac2a7dc71") }
> db.mangCap1.insertOne({ "TenSinhVien": "Robert", "KyNang": ["C", "Java", "C++"] });
{ "acknowledged" : true, "insertedId" : ObjectId("5ca2362766324ffac2a7dc72") }

Tìm sinh viên có kỹ năng "MongoDB" - Cách đơn giản

> db.mangCap1.find({ KyNang: "MongoDB" }).pretty();
{ "_id" : ObjectId("5ca2360f66324ffac2a7dc71"), "TenSinhVien" : "Chris", "KyNang" : [ "MongoDB", "MySQL", "SQL Server" ] }

Tương đương với $in

> db.mangCap1.find({ KyNang: { $in: ["MongoDB"] } }).pretty();

Khi nào CẦN $elemMatch?

Chỉ khi mảng chứa **object** và bạn cần match **nhiều điều kiện trên cùng một element**:

Ví dụ: Mảng object - Cần $elemMatch

// Dữ liệu
{ "sanPham": [ { "ten": "Ao", "gia": 100 }, { "ten": "Quan", "gia": 200 } ] }

// SAI: Tìm sản phẩm tên "Ao" VÀ giá 200 (match cross-element)
db.collection.find({ "sanPham.ten": "Ao", "sanPham.gia": 200 });
// Trả về doc (vì CÓ element tên Ao VÀ CÓ element giá 200)

// ĐÚNG: Tìm element CÓ CẢ tên "Ao" VÀ giá 200
db.collection.find({ sanPham: { $elemMatch: { ten: "Ao", gia: 200 } } });
// Không trả về (không có element nào thỏa cả 2)

Tóm tắt quy tắc chọn

Kiểu mảngTruy vấn đơn giảnCần $elemMatch?
Giá trị đơn giản: ["a", "b", "c"]{ field: "a" } hoặc { field: { $in: ["a"] } }❌ Không
Object: [{a:1,b:2}, {a:3,b:4}]{ "field.a": 1 } (match field đơn lẻ)❌ Không
Object: [{a:1,b:2}, {a:3,b:4}]Cần match a=1 **VÀ** b=2 trên cùng element✅ Có

Lưu ý

  • $elemMatch trên mảng giá trị đơn giản vẫn hoạt động nhưng **thừa thãi** và chậm hơn
  • Truy vấn trực tiếp { tags: "value" } có thể dùng **Multikey Index
  • $elemMatch cũng dùng trong $project (aggregation) để lọc element trong mảng