Để truy vấn mảng các subdocument, sử dụng $unwind trong aggregate để phân rã mảng, sau đó lọc với $match.
Tạo collection với mảng subdocument
> db.demo499.insertOne({
"details": [
{ Name: "MIT", Rank: 1, "CountryName": "US" },
{ Name: "Stanford University", Rank: 2 },
{ Name: "University of California, Berkeley", Rank: 3 }
]
});
Hiển thị document gốc
> db.demo499.find();
Kết quả (1 document, mảng details 3 phần tử):
{
"details": [
{ "Name": "MIT", "Rank": 1, "CountryName": "US" },
{ "Name": "Stanford University", "Rank": 2 },
{ "Name": "University of California, Berkeley", "Rank": 3 }
]
}
Aggregate: unwind + match tồn tại CountryName + project
> db.demo499.aggregate([
{ $unwind: "$details" },
{ $match: { "details.CountryName": { $exists: true } } },
{ $project: { "details.Name": 1, "details.CountryName": 1, _id: 0 } }
])
Kết quả (chỉ MIT có CountryName):
{
"details": { "Name": "MIT", "CountryName": "US" }
}
Giải thích:
$unwind: Tách mảng details thành 3 document riêng$matchvới$exists: true: Chỉ giữ subdocument có trường CountryName$project: Chọn Name và CountryName, ẩn _id
Truy vấn tương tự với find() (trả về document cha):
db.demo499.find({ "details.CountryName": { $exists: true } })
Trả về toàn bộ document cha (kèm 3 subdocument), không lọc được từng phần tử.
Khi nào dùng aggregate vs find:
find(): Cần document cha, điều kiện lọc đơn giảnaggregate($unwind): Cần xử lý, biến đổi, lọc từng subdocument riêng lẻ