Khi truy vấn mảng đối tượng (subcollection), thay vì dùng $and phức tạp, hãy sử dụng $in kết hợp $elemMatch để tìm document chứa phần tử thỏa mãn điều kiện.
Tạo collection với mảng lồng nhau
> db.demo83.insertOne({
... "Details":[
... {
... "Name":"Chris",
... "Subject":["MySQL", "MongoDB"]
... },
... {
... "Name":"David",
... "Subject":["Java", "C"]
... }
... ]
... });
{ "acknowledged" : true, "insertedId" : ObjectId("5e2bfd2271bf0181ecc422a3") }
> db.demo83.insertOne({
... "Details":[
... {
... "Name":"Bob",
... "Subject":["C++", "Python"]
... },
... {
... "Name":"John",
... "Subject":["Spring", "Hibernate"]
... }
... ]
... });
{ "acknowledged" : true, "insertedId" : ObjectId("5e2bfd4571bf0181ecc422a4") }
Truy vấn tìm document có Name="Chris" VÀ Subject chứa "MongoDB"
> db.demo83.find({
"Details" : {
"$elemMatch" : {
"Name" : "Chris",
"Subject": { "$in": ["MongoDB"] }
}
}
});
Kết quả
{ "_id" : ObjectId("5e2bfd2271bf0181ecc422a3"), "Details" : [ { "Name" : "Chris", "Subject" : [ "MySQL", "MongoDB" ] }, { "Name" : "David", "Subject" : [ "Java", "C" ] } ] }
Giải thích:
$elemMatch: Đảm bảo cùng một phần tử mảng thỏa mãn cả hai điều kiện$in: Kiểm tra "MongoDB" có trong mảng Subject không (tương đương $eq cho mảng)- Toán tử
$andkhông cần thiết ở đây vì$elemMatchđã ngầm hiểu logic AND giữa các trường của cùng một phần tử
Cách này ngắn gọn, dễ đọc và hiệu quả hơn so với viết nhiều điều kiện $and riêng lẻ.