Docs Menu
Docs Home
/
MongoDB 매뉴얼
/ / /

$group (집계)

이 페이지의 내용

  • 정의
  • 호환성
  • 구문
  • 고려 사항
  • 예시
  • 추가 리소스
$group

$group 단계는 '그룹 키'에 따라 문서를 그룹으로 분리합니다. 출력은 각 고유 그룹 키당 하나의 문서입니다.

그룹 키는 대부분 필드이거나 필드 그룹입니다. 그룹 키는 표현식의 결과일 수도 있습니다. 그룹 키는 $group 파이프라인 단계의 _id 필드를 사용해 설정할 수 있습니다. 사용 예시는 아래를 참조하세요.

$group 단계 출력에서 _id 필드는 해당 문서의 그룹 키로 설정됩니다.

출력 문서에는 축적자 표현식을 사용하여 설정한 추가 필드도 포함될 수 있습니다.

참고

$group은 출력 문서의 순서를 지정하지 않습니다.

다음 환경에서 호스팅되는 배포에 $group 사용할 수 있습니다.

  • MongoDB Atlas: 클라우드에서의 MongoDB 배포를 위한 완전 관리형 서비스

  • MongoDB Enterprise: MongoDB의 구독 기반 자체 관리 버전

  • MongoDB Community: MongoDB의 소스 사용 가능 무료 자체 관리 버전

$group 단계의 프로토타입 형식은 다음과 같습니다.

{
$group:
{
_id: <expression>, // Group key
<field1>: { <accumulator1> : <expression1> },
...
}
}
필드
설명

_id

필수입니다. _id 표현식 은 그룹 키를 지정합니다._id null 값 또는 기타 상수 값을 $group 지정하는 경우 단계는 모든 입력 문서의 값을 집계하는 단일 문서 를 반환합니다. Null로 그룹화 예시 참조하세요.

field

_id누산기 연산자는 유효한 expression을 모두 허용할 수 있습니다. 표현식에 대한 자세한 내용은 표현식 연산자를 참조하세요.

$group 데이터를 처리하기 전에 파이프라인이 블로킹 단계에서 모든 입력 데이터가 조회될 때까지 대기하도록 하는 블로킹 단계입니다. 블로킹 단계는 여러 단계가 있는 파이프라인에 대한 병렬 처리를 줄이기 때문에 성능을 저하시킬 수 있습니다. 블로킹 단계는 대규모 데이터 세트에 대해 상당한 양의 메모리를 사용할 수도 있습니다.

<accumulator> 연산자는 다음 누산기 연산자 중 하나이어야 합니다.

버전 5.0에서 변경됨

이름
설명

사용자 정의 누산기 함수의 결과를 반환합니다.

각 그룹에 대한 고유한 표현식 값의 배열을 반환합니다. 배열 요소의 순서가 정의되지 않았습니다.

버전 5.0에서 변경: $setWindowFields 단계에서 사용할 수 있습니다.

숫자 값의 평균을 반환합니다. 숫자가 아닌 값을 무시합니다.

버전 5.0에서 변경: $setWindowFields 단계에서 사용할 수 있습니다.

지정된 정렬 순서에 따라 그룹 내 하위 요소를 반환합니다.

버전 5.2에 추가되었습니다.

2} 및 단계에서 $group $setWindowFields 사용할 수 있습니다.

지정된 정렬 순서에 따라 그룹 내 하위 개 요소의 집계를 반환합니다.n

버전 5.2에 추가되었습니다.

2} 및 단계에서 $group $setWindowFields 사용할 수 있습니다.

그룹에 있는 문서 수를 반환합니다.

$count 파이프라인 스테이지와는 다릅니다.

버전 5.2의 새로운 기능: $group$setWindowFields 단계에서 사용할 수 있습니다.

그룹의 첫 번째 문서에 대한 표현식 결과를 반환합니다.

버전 5.0에서 변경: $setWindowFields 단계에서 사용할 수 있습니다.

그룹 내 첫 n 개 요소의 집계를 반환합니다. 문서가 정해진 순서로 정리되어 있을 때만 의미가 있습니다. $firstN 배열 연산자와 다릅니다.

버전 5.2의 새로운 기능: $group, 표현식, $setWindowFields 단계에서 사용할 수 있습니다.

그룹의 마지막 문서에 대한 표현식의 결과를 반환합니다.

버전 5.0에서 변경: $setWindowFields 단계에서 사용할 수 있습니다.

그룹 내 마지막 n 개 요소의 집계를 반환합니다. 문서가 정해진 순서로 정리되어 있을 때만 의미가 있습니다. $lastN 배열 연산자와 다릅니다.

버전 5.2의 새로운 기능: $group, 표현식, $setWindowFields 단계에서 사용할 수 있습니다.

각 그룹에 대해 가장 높은 표현식 값을 반환합니다.

버전 5.0에서 변경: $setWindowFields 단계에서 사용할 수 있습니다.

그룹 내 최댓값을 가진 개 요소의 집계를 반환합니다.n $maxN 배열 연산자와는 다릅니다.

버전 5.2에 추가되었습니다.

$group, $setWindowFields표현식으로 사용할 수 있습니다.

중앙값, 즉 50번째 백분위수의 근사치를 스칼라 값으로 반환합니다.

버전 7.0에 추가.

이 연산자는 이 단계에서 누산기로 사용할 수 있습니다:

집계 표현식으로도 사용할 수 있습니다.

각 그룹에 대한 입력 문서를 결합하여 생성된 문서를 반환합니다.

각 그룹에 대해 가장 낮은 표현식 값을 반환합니다.

버전 5.0에서 변경: $setWindowFields 단계에서 사용할 수 있습니다.

그룹 내 최솟값을 가진 개 요소의 집계를 반환합니다.n $minN 배열 연산자와 다릅니다.

버전 5.2에 추가되었습니다.

$group, $setWindowFields표현식으로 사용할 수 있습니다.

지정된 백분위수 값에 해당하는 스칼라 값의 배열을 반환합니다.

버전 7.0에 추가.

이 연산자는 이 단계에서 누산기로 사용할 수 있습니다:

집계 표현식으로도 사용할 수 있습니다.

각 그룹의 문서에 대한 표현식 값의 배열을 반환합니다.

버전 5.0에서 변경: $setWindowFields 단계에서 사용할 수 있습니다.

입력 값의 모집단 표준 편차를 반환합니다.

버전 5.0에서 변경: $setWindowFields 단계에서 사용할 수 있습니다.

입력 값의 표본 표준 편차를 반환합니다.

버전 5.0에서 변경: $setWindowFields 단계에서 사용할 수 있습니다.

숫자 값의 합계를 반환합니다. 숫자가 아닌 값을 무시합니다.

버전 5.0에서 변경: $setWindowFields 단계에서 사용할 수 있습니다.

지정된 정렬 순서에 따라 그룹 내 최상위 요소를 반환합니다.

버전 5.2에 추가되었습니다.

2} 및 단계에서 $group $setWindowFields 사용할 수 있습니다.

지정된 정렬 순서에 따라 그룹 내 상위 개 요소의 집계를 반환합니다.n

버전 5.2에 추가되었습니다.

2} 및 단계에서 $group $setWindowFields 사용할 수 있습니다.

$group 단계가 100MB의 RAM을 초과하면 MongoDB는 임시 파일에 데이터를 씁니다. 그러나 allowDiskUse 옵션이 false로 설정되어 있으면 $group은 오류를 반환합니다. 자세한 내용은 집계 파이프라인 제한을 참조하세요.

이 섹션에서는 $group의 성능을 개선하기 위한 최적화에 대해 설명합니다. 수동으로 수행할 수 있는 최적화와 MongoDB가 내부적으로 수행할 수 있는 최적화가 있습니다.

파이프라인이 동일한 필드를 기준으로 sorts(정렬) 및 groups(그룹화)를 수행하고, $group 단계에서 $first 또는 $last 누산기 연산자만 사용하는 경우 정렬 순서와 일치하는 그룹화된 필드에 인덱스 를 추가하는 것이 좋습니다. 어떤 경우에는 $group 단계에서 인덱스를 사용하여 각 그룹의 첫 번째 또는 마지막 문서를 빠르게 찾을 수 있습니다.

예시

foo이라는 컬렉션에 { x: 1, y: 1 } 인덱스가 포함된 경우 다음 파이프라인은 해당 인덱스를 사용하여 각 그룹의 첫 번째 문서를 찾을 수 있습니다.

db.foo.aggregate([
{
$sort:{ x : 1, y : 1 }
},
{
$group: {
_id: { x : "$x" },
y: { $first : "$y" }
}
}
])

버전 5.2부터는 다음 중 하나에 해당하는 경우 MongoDB가 슬롯 기반 실행 쿼리 엔진을 사용해 $group 단계를 실행합니다.

  • $group 파이프라인의 첫 번째 단계입니다.

  • 파이프라인의 모든 이전 단계는 슬롯 기반 실행 엔진에 의해 실행될 수도 있습니다.

자세한 내용은 $group 최적화를 참조하세요.

mongosh에서 다음 문서를 사용하여 sales라는 이름의 샘플 컬렉션을 만듭니다.

db.sales.insertMany([
{ "_id" : 1, "item" : "abc", "price" : Decimal128("10"), "quantity" : Int32("2"), "date" : ISODate("2014-03-01T08:00:00Z") },
{ "_id" : 2, "item" : "jkl", "price" : Decimal128("20"), "quantity" : Int32("1"), "date" : ISODate("2014-03-01T09:00:00Z") },
{ "_id" : 3, "item" : "xyz", "price" : Decimal128("5"), "quantity" : Int32( "10"), "date" : ISODate("2014-03-15T09:00:00Z") },
{ "_id" : 4, "item" : "xyz", "price" : Decimal128("5"), "quantity" : Int32("20") , "date" : ISODate("2014-04-04T11:21:39.736Z") },
{ "_id" : 5, "item" : "abc", "price" : Decimal128("10"), "quantity" : Int32("10") , "date" : ISODate("2014-04-04T21:23:13.331Z") },
{ "_id" : 6, "item" : "def", "price" : Decimal128("7.5"), "quantity": Int32("5" ) , "date" : ISODate("2015-06-04T05:08:13Z") },
{ "_id" : 7, "item" : "def", "price" : Decimal128("7.5"), "quantity": Int32("10") , "date" : ISODate("2015-09-10T08:43:00Z") },
{ "_id" : 8, "item" : "abc", "price" : Decimal128("10"), "quantity" : Int32("5" ) , "date" : ISODate("2016-02-06T20:20:13Z") },
])

다음 집계 작업은 $group 단계를 사용하여 sales 컬렉션의 문서 수를 계산합니다.

db.sales.aggregate( [
{
$group: {
_id: null,
count: { $count: { } }
}
}
] )

이 연산은 다음과 같은 결과를 반환합니다.

{ "_id" : null, "count" : 8 }

이 집계 작업은 다음 SQL 문과 동일합니다.

SELECT COUNT(*) AS count FROM sales

다음도 참조하세요.

다음 집계 연산은 $group 단계를 사용하여 sales 컬렉션에서 고유 항목 값을 조회합니다.

db.sales.aggregate( [ { $group : { _id : "$item" } } ] )

이 연산은 다음과 같은 결과를 반환합니다.

{ "_id" : "abc" }
{ "_id" : "jkl" }
{ "_id" : "def" }
{ "_id" : "xyz" }

참고

을 사용하여 샤딩된 컬렉션 에서 고유 값을 조회 할 때 작업 결과 가 발생하면 결과에 $group DISTINCT_SCAN 고아 문서가포함될 수 있습니다.

The only semantically correct 파이프라인 that is impacted is effectively a logical equivalent of a command, where there is distinct a $group stage at or near the beginning of the 파이프라인 and the $group is not preceded by a stage $sort .

예를 예시, 다음 형식의 $group 연산은 DISTINCT_SCAN(이)가 될 수 있습니다.

{ $group : { _id : "$<field>" } }

고유 값을 검색하기 위한 동작에 대한 자세한 내용은 고유 명령 동작을 참조하세요.

작업 결과가 인지 DISTINCT_SCAN 확인하려면작업의 설명 결과를 확인하세요.

다음 집계 작업은 item 필드를 기준으로 문서를 그룹화하여 품목당 총 판매 금액을 계산하고 총 판매 금액이 100 이상인 품목만 반환합니다.

db.sales.aggregate(
[
// First Stage
{
$group :
{
_id : "$item",
totalSaleAmount: { $sum: { $multiply: [ "$price", "$quantity" ] } }
}
},
// Second Stage
{
$match: { "totalSaleAmount": { $gte: 100 } }
}
]
)
첫 번째 단계:
$group 단계는 고유 항목 값을 검색하기 위해 문서를 item으로 그룹화합니다. 이 단계에서는 각 항목에 totalSaleAmount를 반환합니다.
두 번째 단계:
$match 단계는 결과 문서를 필터링하여 totalSaleAmount이(가) 100보다 크거나 같은 항목만 반환합니다.

이 연산은 다음과 같은 결과를 반환합니다.

{ "_id" : "abc", "totalSaleAmount" : Decimal128("170") }
{ "_id" : "xyz", "totalSaleAmount" : Decimal128("150") }
{ "_id" : "def", "totalSaleAmount" : Decimal128("112.5") }

이 집계 작업은 다음 SQL 문과 동일합니다.

SELECT item,
Sum(( price * quantity )) AS totalSaleAmount
FROM sales
GROUP BY item
HAVING totalSaleAmount >= 100

다음도 참조하세요.

mongosh에서 다음 문서를 사용하여 sales라는 이름의 샘플 컬렉션을 만듭니다.

db.sales.insertMany([
{ "_id" : 1, "item" : "abc", "price" : Decimal128("10"), "quantity" : Int32("2"), "date" : ISODate("2014-03-01T08:00:00Z") },
{ "_id" : 2, "item" : "jkl", "price" : Decimal128("20"), "quantity" : Int32("1"), "date" : ISODate("2014-03-01T09:00:00Z") },
{ "_id" : 3, "item" : "xyz", "price" : Decimal128("5"), "quantity" : Int32( "10"), "date" : ISODate("2014-03-15T09:00:00Z") },
{ "_id" : 4, "item" : "xyz", "price" : Decimal128("5"), "quantity" : Int32("20") , "date" : ISODate("2014-04-04T11:21:39.736Z") },
{ "_id" : 5, "item" : "abc", "price" : Decimal128("10"), "quantity" : Int32("10") , "date" : ISODate("2014-04-04T21:23:13.331Z") },
{ "_id" : 6, "item" : "def", "price" : Decimal128("7.5"), "quantity": Int32("5" ) , "date" : ISODate("2015-06-04T05:08:13Z") },
{ "_id" : 7, "item" : "def", "price" : Decimal128("7.5"), "quantity": Int32("10") , "date" : ISODate("2015-09-10T08:43:00Z") },
{ "_id" : 8, "item" : "abc", "price" : Decimal128("10"), "quantity" : Int32("5" ) , "date" : ISODate("2016-02-06T20:20:13Z") },
])

다음 파이프라인은 2014년 한 해 동안의 총 판매 금액, 평균 판매량 및 일일 판매 횟수를 계산합니다.

db.sales.aggregate([
// First Stage
{
$match : { "date": { $gte: new ISODate("2014-01-01"), $lt: new ISODate("2015-01-01") } }
},
// Second Stage
{
$group : {
_id : { $dateToString: { format: "%Y-%m-%d", date: "$date" } },
totalSaleAmount: { $sum: { $multiply: [ "$price", "$quantity" ] } },
averageQuantity: { $avg: "$quantity" },
count: { $sum: 1 }
}
},
// Third Stage
{
$sort : { totalSaleAmount: -1 }
}
])
첫 번째 단계:
$match 단계는 2014년에 작성된 문서만 다음 단계로 전달하도록 문서를 필터링합니다.
두 번째 단계:
$group 단계에서는 문서를 날짜별로 그룹화하고 각 그룹에 있는 문서의 총 판매 금액, 평균 수량 및 총 개수를 계산합니다.
세 번째 단계:
$sort 단계는 각 그룹의 총 판매 금액을 기준으로 결과를 내림차순으로 정렬합니다.

이 연산은 다음과 같은 결과를 반환합니다.

{
"_id" : "2014-04-04",
"totalSaleAmount" : Decimal128("200"),
"averageQuantity" : 15, "count" : 2
}
{
"_id" : "2014-03-15",
"totalSaleAmount" : Decimal128("50"),
"averageQuantity" : 10, "count" : 1
}
{
"_id" : "2014-03-01",
"totalSaleAmount" : Decimal128("40"),
"averageQuantity" : 1.5, "count" : 2
}

이 집계 작업은 다음 SQL 문과 동일합니다.

SELECT date,
Sum(( price * quantity )) AS totalSaleAmount,
Avg(quantity) AS averageQuantity,
Count(*) AS Count
FROM sales
WHERE date >= '01/01/2014' AND date < '01/01/2015'
GROUP BY date
ORDER BY totalSaleAmount DESC

다음도 참조하세요.

다음 집계 작업은 null의 그룹 _id을(를) 지정하여 collection의 총 판매 금액, 평균 수량 및 모든 문서의 개수를 계산합니다.

db.sales.aggregate([
{
$group : {
_id : null,
totalSaleAmount: { $sum: { $multiply: [ "$price", "$quantity" ] } },
averageQuantity: { $avg: "$quantity" },
count: { $sum: 1 }
}
}
])

이 연산은 다음과 같은 결과를 반환합니다.

{
"_id" : null,
"totalSaleAmount" : Decimal128("452.5"),
"averageQuantity" : 7.875,
"count" : 8
}

이 집계 작업은 다음 SQL 문과 동일합니다.

SELECT Sum(price * quantity) AS totalSaleAmount,
Avg(quantity) AS averageQuantity,
Count(*) AS Count
FROM sales

다음도 참조하세요.

mongosh에서 다음 문서를 사용하여 books라는 이름의 샘플 컬렉션을 만듭니다.

db.books.insertMany([
{ "_id" : 8751, "title" : "The Banquet", "author" : "Dante", "copies" : 2 },
{ "_id" : 8752, "title" : "Divine Comedy", "author" : "Dante", "copies" : 1 },
{ "_id" : 8645, "title" : "Eclogues", "author" : "Dante", "copies" : 2 },
{ "_id" : 7000, "title" : "The Odyssey", "author" : "Homer", "copies" : 10 },
{ "_id" : 7020, "title" : "Iliad", "author" : "Homer", "copies" : 10 }
])

다음 집계 작업은 books collection의 데이터를 피봇하여 작성자별로 제목을 그룹화합니다.

db.books.aggregate([
{ $group : { _id : "$author", books: { $push: "$title" } } }
])

이 작업은 다음 문서를 반환합니다.

{ "_id" : "Homer", "books" : [ "The Odyssey", "Iliad" ] }
{ "_id" : "Dante", "books" : [ "The Banquet", "Divine Comedy", "Eclogues" ] }

다음 집계 작업은 author를 기준으로 문서를 그룹화합니다.

db.books.aggregate([
// First Stage
{
$group : { _id : "$author", books: { $push: "$$ROOT" } }
},
// Second Stage
{
$addFields:
{
totalCopies : { $sum: "$books.copies" }
}
}
])
첫 번째 단계:

$group$$ROOT 시스템 변수를 사용하여 전체 문서를 작성자별로 그룹화합니다. 이 단계에서는 다음 문서를 다음 단계로 전달합니다.

{ "_id" : "Homer",
"books" :
[
{ "_id" : 7000, "title" : "The Odyssey", "author" : "Homer", "copies" : 10 },
{ "_id" : 7020, "title" : "Iliad", "author" : "Homer", "copies" : 10 }
]
},
{ "_id" : "Dante",
"books" :
[
{ "_id" : 8751, "title" : "The Banquet", "author" : "Dante", "copies" : 2 },
{ "_id" : 8752, "title" : "Divine Comedy", "author" : "Dante", "copies" : 1 },
{ "_id" : 8645, "title" : "Eclogues", "author" : "Dante", "copies" : 2 }
]
}
두 번째 단계:

$addFields 은(는) 각 저자의 총 책 부수를 포함하는 필드를 출력에 추가합니다.

참고

결과 문서는 BSON 문서 크기 제한인 16메가바이트를 초과하지 않아야 합니다.

이 작업은 다음 문서를 반환합니다.

{
"_id" : "Homer",
"books" :
[
{ "_id" : 7000, "title" : "The Odyssey", "author" : "Homer", "copies" : 10 },
{ "_id" : 7020, "title" : "Iliad", "author" : "Homer", "copies" : 10 }
],
"totalCopies" : 20
}
{
"_id" : "Dante",
"books" :
[
{ "_id" : 8751, "title" : "The Banquet", "author" : "Dante", "copies" : 2 },
{ "_id" : 8752, "title" : "Divine Comedy", "author" : "Dante", "copies" : 1 },
{ "_id" : 8645, "title" : "Eclogues", "author" : "Dante", "copies" : 2 }
],
"totalCopies" : 5
}

다음도 참조하세요.

우편번호 데이터 세트를 사용한 집계 튜토리얼에서는 $group 연산자에 관한 광범위한 일반 사용 사례 예시를 설명합니다.

돌아가기

$graphLookup