모든 문서에 걸쳐 고유한 값의 개수를 계산하려면 MongoDB의 aggregate() 메서드를 사용해야 합니다. 집계 파이프라인에서 $unwind로 배열을 펼치고, $match로 조건에 맞는 문서를 필터링한 뒤, $addToSet으로 중복 없는 값만 수집하고 마지막에 $size로 개수를 구하면 됩니다.
1. 컬렉션 생성 및 문서 삽입
먼저 데모용 컬렉션을 생성하고 문서를 삽입해 보겠습니다.
> db.demo718.insertOne(
... {
... "id":101,
... "details":
... {
... "OtherDetails": ["Chris", "Mike", "Sam"], "GroupName": ["Group-1"], "Info": []
... }
... }
... );
{
"acknowledged" : true,
"insertedId" : ObjectId("5eaae25843417811278f5880")
}
> db.demo718.insertOne(
... {
... "id":102,
... "details":
... {
... "OtherDetails": ["Chris", "David"], "GroupName": ["Group-1"], "Info": []
... }
... }
... );
{
"acknowledged" : true,
"insertedId" : ObjectId("5eaae25943417811278f5881")
}2. find()로 저장된 문서 확인하기
find() 메서드를 사용하면 컬렉션에 저장된 모든 문서를 조회할 수 있습니다.
> db.demo718.find();
위 명령을 실행하면 다음과 같은 결과가 출력됩니다.
{ "_id" : ObjectId("5eaae25843417811278f5880"), "id" : 101, "details" : { "OtherDetails" : [ "Chris", "Mike", "Sam" ], "GroupName" : [ "Group-1" ], "Info" : [ ] } }
{ "_id" : ObjectId("5eaae25943417811278f5881"), "id" : 102, "details" : { "OtherDetails" : [ "Chris", "David" ], "GroupName" : [ "Group-1" ], "Info" : [ ] } }3. 고유 값 개수를 계산하는 집계 쿼리
다음은 모든 문서에 걸쳐 고유한(distinct) 값의 개수를 계산하는 쿼리입니다.
> db.demo718.aggregate([
... {
... $unwind: "$details.GroupName"
... },
... {
... $match: {
... "details.GroupName": "Group-1"
... }
... },
... {
... $unwind: "$details.OtherDetails"
... },
... {
... $group: {
... _id: "$details.GroupName",
... OtherDetailsUnique: {
... $addToSet: "$details.OtherDetails"
... }
... }
... },
... {
... $project: {
... _id : 0,
... GROUP_NAME: "$_id",
... OtherDetailsUniqueCount: {
... $size: "$OtherDetailsUnique"
... }
... }
... }
... ])파이프라인 단계별 동작 원리
- $unwind: GroupName 배열을 개별 문서 단위로 펼칩니다.
- $match: GroupName이 "Group-1"인 문서만 남깁니다.
- $unwind: OtherDetails 배열을 다시 개별 값으로 펼칩니다.
- $group + $addToSet: 그룹별로 중복을 제거한 고유 값 목록을 수집합니다.
- $project + $size: 고유 값 배열의 크기, 즉 개수를 계산해 최종 출력합니다.
위 쿼리를 실행하면 다음과 같은 결과가 출력됩니다.
{ "GROUP_NAME" : "Group-1", "OtherDetailsUniqueCount" : 4 }결과를 해석해 보면, "Group-1" 그룹에 속한 문서들의 OtherDetails 배열에는 Chris, Mike, Sam, David 등 총 4개의 고유한 이름이 존재합니다. 두 문서에 모두 포함된 "Chris"는 중복되지만, $addToSet이 자동으로 중복을 제거해 주기 때문에 한 번만 계산됩니다. 이처럼 집계 파이프라인을 활용하면 여러 문서에 흩어진 배열 데이터에서도 손쉽게 고유 값의 개수를 구할 수 있습니다.