MongoDB에서 하위 문서 필드 값의 고유한(distinct) 목록 얻기
MongoDB에서 하위 문서(sub-document) 내부에 있는 필드 값들의 고유한 목록을 조회하려면 점(.) 표기법을 활용하면 됩니다. 외부 필드 이름과 내부 필드 이름을 점으로 연결하여 distinct() 메서드에 전달하면, 배열 형태로 중복이 제거된 값들을 손쉽게 얻을 수 있습니다.
기본 문법
db.yourCollectionName.distinct("yourOuterFieldName.yourInnerFieldName");즉, 컬렉션 이름 뒤에 distinct()를 붙이고, 인자로 "외부필드명.내부필드명" 형식의 문자열을 넘겨주면 해당 경로에 있는 모든 값을 순회하며 고유한 값만 반환합니다.
실습: 샘플 컬렉션 생성
개념을 이해하기 위해 실제 문서가 포함된 컬렉션을 만들어 보겠습니다. 아래 쿼리는 학생 정보를 담은 세 개의 문서를 삽입합니다.
> db.getDistinctListOfSubDocumentFieldDemo.insertOne(
... {
... "StudentId": 101,
... "StudentPersonalDetails": [
... {
... "StudentName": "John",
... "StudentAge": 24
... },
... {
... "StudentName": "Carol",
... "StudentAge": 21
... }
... ]
... }
... );
{
"acknowledged" : true,
"insertedId" : ObjectId("5c90a9abb74d7cfe6392d7d8")
}같은 방식으로 두 번째 문서도 삽입합니다.
> db.getDistinctListOfSubDocumentFieldDemo.insertOne(
... {
... "StudentId": 102,
... "StudentPersonalDetails": [
... {
... "StudentName": "Carol",
... "StudentAge": 26
... },
... {
... "StudentName": "Bob",
... "StudentAge": 21
... }
... ]
... }
... );
{
"acknowledged" : true,
"insertedId" : ObjectId("5c90a9ceb74d7cfe6392d7d9")
}세 번째 문서까지 추가합니다.
> db.getDistinctListOfSubDocumentFieldDemo.insertOne(
... {
... "StudentId": 103,
... "StudentPersonalDetails": [
... {
... "StudentName": "Bob",
... "StudentAge": 25
... },
... {
... "StudentName": "David",
... "StudentAge": 24
... }
... ]
... }
... );
{
"acknowledged" : true,
"insertedId" : ObjectId("5c90a9e6b74d7cfe6392d7da")
}저장된 문서 확인하기
find() 메서드를 사용해 컬렉션의 모든 문서를 확인할 수 있습니다.
> db.getDistinctListOfSubDocumentFieldDemo.find().pretty();
실행 결과는 다음과 같습니다.
{
"_id" : ObjectId("5c90a9abb74d7cfe6392d7d8"),
"StudentId" : 101,
"StudentPersonalDetails" : [
{
"StudentName" : "John",
"StudentAge" : 24
},
{
"StudentName" : "Carol",
"StudentAge" : 21
}
]
}
{
"_id" : ObjectId("5c90a9ceb74d7cfe6392d7d9"),
"StudentId" : 102,
"StudentPersonalDetails" : [
{
"StudentName" : "Carol",
"StudentAge" : 26
},
{
"StudentName" : "Bob",
"StudentAge" : 21
}
]
}
{
"_id" : ObjectId("5c90a9e6b74d7cfe6392d7da"),
"StudentId" : 103,
"StudentPersonalDetails" : [
{
"StudentName" : "Bob",
"StudentAge" : 25
},
{
"StudentName" : "David",
"StudentAge" : 24
}
]
}살펴보면 각 문서의 StudentPersonalDetails 배열 안에 여러 명의 학생 정보가 들어 있으며, 일부 이름(Carol, Bob)은 서로 다른 문서에서 반복되고 있습니다.
고유한 필드 값 목록 조회하기
이제 점 표기법을 활용해 하위 문서 필드인 StudentName의 고유한 값 목록을 조회해 보겠습니다.
> db.getDistinctListOfSubDocumentFieldDemo.distinct("StudentPersonalDetails.StudentName");실행 결과는 다음과 같습니다.
[ "Carol", "John", "Bob", "David" ]
모든 문서의 하위 문서를 훑어보면서 StudentName 값을 수집하고, 중복된 "Carol"과 "Bob"은 한 번씩만 남긴 결과를 확인할 수 있습니다.
정리
- 하위 문서 필드의 고유한 값 목록이 필요할 때는
distinct()메서드와 점(.) 표기법을 함께 사용합니다. - 형식은
외부필드명.내부필드명이며, 배열 안의 요소들도 자동으로 탐색됩니다. - 반환값은 중복이 제거된 값들의 배열입니다.
이 방법은 집계 파이프라인($group) 없이 간단히 중복 제거된 값 목록이 필요할 때 매우 유용하게 활용할 수 있습니다.