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

Truy vấn object trong mảng (array of objects) với $elemMatch trong MongoDB

Khi cần tìm document mà **một phần tử** trong mảng object thỏa mãn **nhiều điều kiện cùng lúc**, hãy dùng $elemMatch. Nếu chỉ một điều kiện, dot notation thường đủ.

Cú pháp

db.collection.find({
    "trườngMảng": { $elemMatch: { "trườngCon1": giáTrị1, "trườngCon2": giáTrị2 } }
}).pretty();

Ví dụ minh họa

Tạo collection objectInAnArrayDemo với mảng StudentDetails chứa các object:

> db.objectInAnArrayDemo.insertOne({
    "StudentDetails": [
        { "StudentName": "John", "StudentMessage": "Hi" },
        { "StudentName": "Larry", "StudentMessage": "Hello" }
    ]
});
> db.objectInAnArrayDemo.insertOne({
    "StudentDetails": [
        { "StudentName": "Carol", "StudentMessage": "Hello" },
        { "StudentName": "David", "StudentMessage": "Good Morning" }
    ]
});

Hiển thị tất cả:

> db.objectInAnArrayDemo.find().pretty();

Kết quả:

{
    "_id" : ObjectId("..."),
    "StudentDetails" : [
        { "StudentName" : "John", "StudentMessage" : "Hi" },
        { "StudentName" : "Larry", "StudentMessage" : "Hello" }
    ]
}
{
    "_id" : ObjectId("..."),
    "StudentDetails" : [
        { "StudentName" : "Carol", "StudentMessage" : "Hello" },
        { "StudentName" : "David", "StudentMessage" : "Good Morning" }
    ]
}

Tìm document có phần tử StudentMessage = "Good Morning"

> db.objectInAnArrayDemo.find({
    "StudentDetails": { $elemMatch: { "StudentMessage": "Good Morning" } }
}).pretty();

Kết quả: Trả về document thứ 2 (chứa David).

{
    "_id" : ObjectId("..."),
    "StudentDetails" : [
        { "StudentName" : "Carol", "StudentMessage" : "Hello" },
        { "StudentName" : "David", "StudentMessage" : "Good Morning" }
    ]
}

Tại sao cần $elemMatch?

So sánh 2 truy vấn trên mảng object [{a:1, b:10}, {a:2, b:20}]:

Truy vấnKết quảGiải thích
{ "arr.a": 1, "arr.b": 20 }Khớp (True)Dot notation: a=1 ở phần tử 1, b=20 ở phần tử 2 -> **khớp cross-element**
{ "arr": { $elemMatch: { a: 1, b: 20 } } }Không khớp (False)$elemMatch: Yêu cầu **CÙNG MỘT** phần tử có a=1 VÀ b=20
{ "arr": { $elemMatch: { a: 1, b: 10 } } }Khớp (True)Phần tử 1 thỏa cả 2 điều kiện

Khi nào dùng $elemMatch?

  • Mảng chứa **object** (không phải giá trị đơn giản).
  • Cần khớp **nhiều field** trên **cùng một** element.
  • Kết hợp với các toán tử so sánh ($gt, $lt, $regex...).

Lưu ý

  • $elemMatch không thể dùng với mảng giá trị nguyên thủy (string, number) - dùng dot notation hoặc $in/$all.
  • Chỉ trả về document cha, không trả về chỉ element khớp (dùng aggregation $filter hoặc $elemMatch trong projection để lấy element con).