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

Lấy danh sách giá trị distinct của trường lồng nhau (sub-document) trong MongoDB

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ảng StudentPersonalDetails và lấy giá trị StudentName củ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 } }
]);