MongoDB $group과 $push로 값 목록 가져오기
MongoDB에서 특정 필드를 기준으로 문서를 그룹화하고, 각 그룹에 속한 값들을 배열(목록) 형태로 한 번에 조회하려면 $group 집계 단계와 $push 연산자를 조합하면 됩니다. 이 글에서는 실제 예제를 통해 그 과정을 단계별로 살펴보겠습니다.
1단계: 샘플 컬렉션 생성
먼저 예제에 사용할 문서들이 담긴 컬렉션을 만듭니다. 아래에서는 사용자별로 수강한 과목 정보를 저장하는 groupByDemo 컬렉션을 생성하고 있습니다.
> db.groupByDemo.insertOne({"UserName":"John","Subject":"MongoDB"});
{
"acknowledged" : true,
"insertedId" : ObjectId("5cd69f0457806ebf1256f136")
}
> db.groupByDemo.insertOne({"UserName":"Larry","Subject":"MySQL"});
{
"acknowledged" : true,
"insertedId" : ObjectId("5cd69f0657806ebf1256f137")
}
> db.groupByDemo.insertOne({"UserName":"John","Subject":"Java"});
{
"acknowledged" : true,
"insertedId" : ObjectId("5cd69f0d57806ebf1256f138")
}
> db.groupByDemo.insertOne({"UserName":"John","Subject":"C"});
{
"acknowledged" : true,
"insertedId" : ObjectId("5cd69f1357806ebf1256f139")
}
> db.groupByDemo.insertOne({"UserName":"Larry","Subject":"SQL Server"});
{
"acknowledged" : true,
"insertedId" : ObjectId("5cd69f1c57806ebf1256f13a")
}2단계: 전체 문서 확인하기
find() 메서드를 사용하면 컬렉션에 저장된 모든 문서를 확인할 수 있습니다.
> db.groupByDemo.find().pretty();
위 쿼리를 실행하면 다음과 같은 결과가 출력됩니다.
{
"_id" : ObjectId("5cd69f0457806ebf1256f136"),
"UserName" : "John",
"Subject" : "MongoDB"
}
{
"_id" : ObjectId("5cd69f0657806ebf1256f137"),
"UserName" : "Larry",
"Subject" : "MySQL"
}
{
"_id" : ObjectId("5cd69f0d57806ebf1256f138"),
"UserName" : "John",
"Subject" : "Java"
}
{
"_id" : ObjectId("5cd69f1357806ebf1256f139"),
"UserName" : "John",
"Subject" : "C"
}
{
"_id" : ObjectId("5cd69f1c57806ebf1256f13a"),
"UserName" : "Larry",
"Subject" : "SQL Server"
}3단계: $group과 $push로 값 목록 조회하기
이제 핵심인 $group과 $push를 활용한 쿼리입니다. _id에는 그룹화 기준이 될 필드($UserName)를 지정하고, $push를 사용해 각 그룹에 속한 Subject 값들을 하나의 배열로 모아줍니다.
> db.groupByDemo.aggregate({$group: { '_id': '$UserName', 'Subject': { $push: '$Subject'}}});실행 결과는 다음과 같습니다. 사용자 이름별로 해당 사용자가 수강한 과목들이 배열로 묶여 출력되는 것을 확인할 수 있습니다.
{ "_id" : "Larry", "Subject" : [ "MySQL", "SQL Server" ] }
{ "_id" : "John", "Subject" : [ "MongoDB", "Java", "C" ] }참고: 중복 제거가 필요하다면?
그룹 내에서 중복 없이 고유한 값만 모으고 싶다면 $push 대신 $addToSet 연산자를 사용하면 됩니다. 두 연산자의 사용 문법은 동일하지만, $addToSet은 이미 배열에 존재하는 값은 추가하지 않는다는 차이점이 있습니다.