Sử dụng phương thức distinct() kết hợp với ký hiệu dấu chấm (.) để truy cập trường con bên trong sub-document hoặc mảng sub-document.
Cú pháp
db.collection.distinct("trườngCha.trườngCon");
Ví dụ minh họa
Tạo collection getDistinctListOfSubDocumentFieldDemo với mảng sub-document StudentPersonalDetails:
> db.getDistinctListOfSubDocumentFieldDemo.insertOne({
"StudentId": 101,
"StudentPersonalDetails": [
{ "StudentName": "John", "StudentAge": 24 },
{ "StudentName": "Carol", "StudentAge": 21 }
]
});
> db.getDistinctListOfSubDocumentFieldDemo.insertOne({
"StudentId": 102,
"StudentPersonalDetails": [
{ "StudentName": "Carol", "StudentAge": 26 },
{ "StudentName": "Bob", "StudentAge": 21 }
]
});
> db.getDistinctListOfSubDocumentFieldDemo.insertOne({
"StudentId": 103,
"StudentPersonalDetails": [
{ "StudentName": "Bob", "StudentAge": 25 },
{ "StudentName": "David", "StudentAge": 24 }
]
});
Hiển thị tất cả:
> db.getDistinctListOfSubDocumentFieldDemo.find().pretty();
Kết quả:
{
"_id" : ObjectId("..."),
"StudentId" : 101,
"StudentPersonalDetails" : [
{ "StudentName" : "John", "StudentAge" : 24 },
{ "StudentName" : "Carol", "StudentAge" : 21 }
]
}
{
"_id" : ObjectId("..."),
"StudentId" : 102,
"StudentPersonalDetails" : [
{ "StudentName" : "Carol", "StudentAge" : 26 },
{ "StudentName" : "Bob", "StudentAge" : 21 }
]
}
{
"_id" : ObjectId("..."),
"StudentId" : 103,
"StudentPersonalDetails" : [
{ "StudentName" : "Bob", "StudentAge" : 25 },
{ "StudentName" : "David", "StudentAge" : 24 }
]
}
Lấy distinct tên học sinh (StudentName) từ mảng sub-document
> db.getDistinctListOfSubDocumentFieldDemo.distinct("StudentPersonalDetails.StudentName");
Kết quả:
[ "Carol", "John", "Bob", "David" ]
Lưu ý quan trọng
distinct()tự động "unwind" mảng: nó xem xét từng phần tử trong mảngStudentPersonalDetailsvà lấy giá trịStudentNamecủa từng phần tử.- Kết quả trả về là mảng các giá trị duy nhất (không trùng lặp).
- Có thể dùng với sub-document đơn (không phải mảng):
db.coll.distinct("address.city"). - Giới hạn: Kết quả distinct không được vượt quá 16MB (kích thước document tối đa). Với dữ liệu lớn, hãy dùng Aggregation Pipeline (
$group+$addToSet).
Ví dụ Aggregation thay thế cho dữ liệu lớn
db.collection.aggregate([
{ $unwind: "$StudentPersonalDetails" },
{ $group: { _id: null, uniqueNames: { $addToSet: "$StudentPersonalDetails.StudentName" } } },
{ $project: { _id: 0, uniqueNames: 1 } }
]);