정의
$group$group 스테이지는 그룹 키에 따라 동일한 필드, 필드들 또는 표현식을 가진 여러 문서를 단일 문서로 결합합니다. 결과는 고유한 그룹 키당 하나의 문서입니다.
A group key is often a field, or group of fields. The group key can also be the result of an expression. Use the
_idfield in the$grouppipeline stage to set the group key. See below for usage examples.$group단계 출력에서_id필드는 해당 문서의 그룹 키로 설정됩니다.The output documents can also contain additional fields that are set using accumulator expressions.
참고
$groupdoes not order its output documents.
호환성
다음 환경에서 호스팅되는 배포에 $group 사용할 수 있습니다.
- MongoDB Atlas: The fully managed service for MongoDB deployments in the cloud
MongoDB Enterprise: MongoDB의 구독 기반 자체 관리 버전
MongoDB Community: MongoDB의 소스 사용 가능 무료 자체 관리 버전
구문
The $group stage has the following prototype form:
{ $group: { _id: <expression>, // Group key <field1>: { <accumulator1> : <expression1> }, ... } }
필드 | 설명 |
|---|---|
| 필수 사항. |
| Optional. Computed using the accumulator operators. |
The _id and the accumulator operators can accept any valid expression. For more information on expressions, see Expressions.
고려 사항
성능
$group 데이터를 처리하기 전에 파이프라인이 블로킹 단계에서 모든 입력 데이터가 조회될 때까지 대기하도록 하는 블로킹 단계입니다. 블로킹 단계는 여러 단계가 있는 파이프라인에 대한 병렬 처리를 줄이기 때문에 성능을 저하시킬 수 있습니다. 블로킹 단계는 대규모 데이터 세트에 대해 상당한 양의 메모리를 사용할 수도 있습니다.
누산기 연산자
<accumulator> 연산자는 다음 누산기 연산자 중 하나이어야 합니다.
이름 | 설명 |
|---|---|
사용자 정의 누산기 함수의 결과를 반환합니다. | |
각 그룹에 대한 고유한 표현식 값의 배열을 반환합니다. 배열 요소의 순서가 정의되지 않았습니다. | |
숫자 값의 평균을 반환합니다. | |
지정된 정렬 순서에 따라 그룹 내 하위 요소를 반환합니다. | |
지정된 정렬 순서에 따라 그룹 내 하위 개 요소의 집계를 반환합니다. | |
둘 이상의 배열의 요소를 결합한 단일 배열 반환합니다. 버전 8.1에 추가 되었습니다. | |
그룹에 있는 문서 수를 반환합니다.
| |
그룹의 첫 번째 문서에 대한 표현식 결과를 반환합니다. | |
그룹 내 첫 | |
그룹의 마지막 문서에 대한 표현식의 결과를 반환합니다. | |
그룹 내 마지막 n개 요소에 대한 지정된 표현식 평가 결과를 반환합니다. | |
각 그룹에 대해 가장 높은 표현식 값을 반환합니다. | |
그룹 내 최댓값을 가진 개 요소의 집계를 반환합니다. | |
그룹의 문서 값의 중앙값(50번째 백분위)의 근사치를 반환합니다. 버전 7.0에 추가 되었습니다. | |
각 그룹에 대한 입력 문서를 결합하여 생성된 문서를 반환합니다. | |
각 그룹에 대해 가장 낮은 표현식 값을 반환합니다. | |
그룹 내 최솟값을 가진 개 요소의 집계를 반환합니다. | |
지정된 백분위수 값에 해당하는 스칼라 값의 배열을 반환합니다. 버전 7.0에 추가 되었습니다. | |
각 그룹의 문서에 대한 표현식 값의 배열을 반환합니다. | |
배열을 2개 이상 가져온 다음 어떤 입력 배열에도 표시되는 요소가 포함된 배열을 1개 반환합니다. 버전 8.1에 추가 되었습니다. | |
그룹의 문서에서의 값의 모집단 표준 편차를 반환합니다. | |
그룹의 문서에서 값의 샘플 표준 편차를 반환합니다. | |
숫자 값의 합계를 반환합니다. 숫자가 아닌 값을 무시합니다. | |
지정된 정렬 순서에 따라 그룹 내 최상위 요소를 반환합니다. | |
지정된 정렬 순서에 따라 그룹 내 상위 개 요소의 집계를 반환합니다. |
빈 필드 이름 제한
$group 단계에는 빈 필드 이름이 있는 축적자 표현식을 포함할 수 없습니다. 자세한 내용은 빈 필드 이름 $group 제한을 참조하세요.
$group 및 메모리 제한
If the $group stage exceeds 100 megabytes of RAM, MongoDB writes data to temporary files. However, if the allowDiskUse option is set to false, $group returns an error. For more information, refer to aggregation pipeline limits.
$group 성능 최적화
This section describes optimizations to improve the performance of $group. There are optimizations that you can make manually and optimizations MongoDB makes internally.
각 그룹의 첫 번째 또는 마지막 문서 반환 최적화
If a pipeline sorts and groups by the same field and the $group stage only uses the $first or $last accumulator operator, consider adding an index on the grouped field which matches the sort order. In some cases, the $group stage can use the index to quickly find the first or last document of each group.
예시
movies 컬렉션 { year: 1, title: 1 } 인덱스 포함된 경우 다음 파이프라인 해당 인덱스 사용하여 각 그룹 의 첫 번째 document 찾을 수 있습니다.
db.movies.aggregate([ { $sort: { year: 1, title: 1 } }, { $group: { _id: { year: "$year" }, title: { $first: "$title" } } } ])
슬롯 기반 쿼리 실행 엔진
Starting in version 5.2, MongoDB uses the slot-based execution query engine to execute $group stages if either:
$group파이프라인의 첫 번째 단계입니다.파이프라인의 모든 이전 단계는 슬롯 기반 실행 엔진에 의해 실행될 수도 있습니다.
자세한 내용은 $group 최적화를 참조하세요.
예시
컬렉션 내의 문서 수 계산
이 페이지의 예시는 sample_mflix 데이터 세트의 데이터를 사용합니다. 이 데이터 세트를 자체 관리형 MongoDB 배포서버에 로드하는 방법에 대한 자세한 내용은 샘플 데이터세트 로드를 참조하세요. 샘플 데이터베이스를 수정한 경우, 이 페이지의 예시를 실행하려면 데이터베이스를 제거하고 다시 생성해야 할 수 있습니다.
The following aggregation operation uses the $group stage to count the number of documents in the movies collection:
db.movies.aggregate([ { $group: { _id: null, count: { $count: {} } } } ])
[ { _id: null, count: 21349 } ]
이 집계 작업은 다음 SQL 문과 동일합니다.
SELECT COUNT(*) AS count FROM movies
Retrieve Distinct Values
다음 집계 작업은 $group 단계를 사용하여 movies 컬렉션에서 고유한 rated 값을 조회합니다:
db.movies.aggregate( [ { $group : { _id : "$rated" } } ] )
[ { _id: 'TV-PG' }, { _id: 'PG' }, { _id: 'TV-14' }, { _id: 'OPEN' }, { _id: 'Not Rated' }, { _id: 'GP' }, { _id: 'TV-Y7' }, { _id: 'G' }, { _id: 'PG-13' }, { _id: null }, { _id: 'M' }, { _id: 'R' }, { _id: 'TV-MA' }, { _id: 'APPROVED' }, { _id: 'PASSED' }, { _id: 'Approved' }, { _id: 'AO' }, { _id: 'TV-G' } ]
참고
예시 들어, 다음 형식의 $group 연산은 DISTINCT_SCAN이(가) 발생할 수 있습니다.
{ $group : { _id : "$<field>" } }
고유 값을 검색하기 위한 동작에 대한 자세한 내용은 고유 명령 동작을 참조하세요.
작업 결과가 인지 DISTINCT_SCAN 확인하려면작업의 설명 결과를 확인하세요.
등급별 그룹화
다음 집계 게이션 작업은 rated 필드 기준으로 문서를 그룹화하여 등급별 총 런타임을 계산하고 총 런타임이 100000 이상인 등급만 반환합니다.
db.movies.aggregate( [ // First Stage { $group: { _id: "$rated", totalRuntime: { $sum: "$runtime" } } }, // Second Stage { $match: { "totalRuntime": { $gte: 100000 } } } ] )
[ { _id: 'PG-13', totalRuntime: 250843 }, { _id: 'R', totalRuntime: 582318 }, { _id: null, totalRuntime: 967127 }, { _id: 'PG', totalRuntime: 191204 } ]
- 첫 번째 단계:
- The
$groupstage groups the documents byratedto retrieve the distinct rating values. This stage returns thetotalRuntimefor each rating group. - 두 번째 단계:
- The
$matchstage filters the resulting document to return only ratings with atotalRuntimegreater than or equal to 100000.
이 집계 작업은 다음 SQL 문과 동일합니다.
SELECT rated, Sum(runtime) AS totalRuntime FROM movies GROUP BY rated HAVING totalRuntime >= 100000
개수, 합계 및 평균 계산
연도별 그룹화
다음 파이프라인 1910 이전 연도의 총 런타임, 평균 런타임 및 영화 수를 계산합니다.
db.movies.aggregate([ { $match: { "year": { $lt: 1910 } } }, { $group: { _id: "$year", totalRuntime: { $sum: "$runtime" }, averageRuntime: { $avg: "$runtime" }, count: { $sum: 1 } } }, { $sort: { totalRuntime: -1 } } ])
[ { _id: 1909, totalRuntime: 14, averageRuntime: 14, count: 1 }, { _id: 1903, totalRuntime: 11, averageRuntime: 11, count: 1 }, { _id: 1896, totalRuntime: 2, averageRuntime: 1, count: 2 } ]
- 첫 번째 단계:
$match단계는 1910 이전에 개봉한 영화만 다음 단계로 전달하도록 문서를 필터링합니다.- 두 번째 단계:
- The
$groupstage groups the documents by year and calculates the total runtime, average runtime, and total count of the documents in each group. - 세 번째 단계:
$sort단계는 각 그룹의 총 런타임을 기준으로 결과를 내림차순으로 정렬합니다.
이 집계 작업은 다음 SQL 문과 동일합니다.
SELECT year, Sum(runtime) AS totalRuntime, Avg(runtime) AS averageRuntime, Count(*) AS count FROM movies WHERE year < 1910 GROUP BY year ORDER BY totalRuntime DESC
팁
db.collection.countDocuments()which wraps the$groupaggregation stage with a$sumexpression.
그룹화 기준 null
다음 집계 작업은 null의 _id 그룹 지정하여 컬렉션 에 있는 모든 문서의 총 런타임, 평균 런타임 및 개수를 계산합니다.
db.movies.aggregate([ { $group: { _id: null, totalRuntime: { $sum: "$runtime" }, averageRuntime: { $avg: "$runtime" }, count: { $sum: 1 } } } ])
[ { _id: null, totalRuntime: 2167458, averageRuntime: 103.65652797704448, count: 21349 } ]
이 집계 작업은 다음 SQL 문과 동일합니다.
SELECT Sum(runtime) AS totalRuntime, Avg(runtime) AS averageRuntime, Count(*) AS count FROM movies
팁
db.collection.countDocuments()which wraps the$groupaggregation stage with a$sumexpression.
Pivot Data
연도별 제목 그룹화
다음 집계 작업은 movies 컬렉션 의 데이터를 피벗하여 연도별로 제목을 그룹 합니다.
db.movies.aggregate([ { $match: { year: { $lt: 1910 } } }, { $group: { _id: "$year", titles: { $push: "$title" } } }, { $sort: { _id: 1 } } ])
[ { _id: 1896, titles: [ 'The Kiss', 'The Kiss' ] }, { _id: 1903, titles: [ 'The Great Train Robbery' ] }, { _id: 1909, titles: [ 'A Corner in Wheat' ] } ]
연도별 문서 그룹화
다음 집계 작업은 문서를 연도별로 그룹화합니다.
db.movies.aggregate([ { $match: { year: { $lt: 1910 } } }, { $group: { _id: "$year", movies: { $push: "$$ROOT" } } }, { $addFields: { totalRuntime: { $sum: "$movies.runtime" } } }, { $sort: { _id: 1 } } ])
[ { _id: 1896, movies: '...', totalRuntime: 2 }, { _id: 1903, movies: '...', totalRuntime: 11 }, { _id: 1909, movies: '...', totalRuntime: 14 } ]
- 첫 번째 단계:
$match1910 이전에 개봉한 영화만 다음 단계로 전달하도록 문서를 필터링합니다.- 두 번째 단계:
$groupuses the$$ROOTsystem variable to group the entire documents by year.- 세 번째 단계:
$addFields각 연도의 총 영화 상영 시간을 포함하는 필드 출력에 추가합니다.참고
결과 문서는 BSON 문서 크기 제한인 16메비바이트를 초과할 수 없습니다.
- 네 번째 단계:
$sort는 결과 문서를_id기준으로 오름차순으로 정렬합니다.
다음 Movie 클래스는 sample_mflix.movies 컬렉션의 문서를 모델링합니다.
[] public class Movie { [] public ObjectId Id { get; set; } [] public string Title { get; set; } = null!; [] public int? Year { get; set; } [] public int? Runtime { get; set; } [] public string? Rated { get; set; } [] public int Metacritic { get; set; } [] public string? Plot { get; set; } [] public string? Type { get; set; } [] public string[]? Cast { get; set; } [] public string[]? Directors { get; set; } [] public string[]? Writers { get; set; } [] public ImdbData? Imdb { get; set; } }
var pipeline = new EmptyPipelineDefinition<Movie>() .Group( id: m => m.Rated, group: g => new { Rating = g.Key, TotalRuntime = g.Sum(m => m.Runtime), MedianRuntime = g.Select(m => m.Runtime).Median(), NinetiethPercentileRuntime = g.Select(m => m.Runtime).Percentile(new[] { 0.9 }) } );
이 페이지의 Node.js 예제에서는 Atlas 샘플 데이터 세트의 sample_mflix 데이터베이스 사용합니다. 무료 MongoDB Atlas cluster 생성하고 샘플 데이터 세트를 로드하는 방법을 학습하려면 MongoDB Node.js 운전자 설명서에서 시작하기 를 참조하세요.
MongoDB Node.js 운전자 사용하여 집계 파이프라인 에 $group 단계를 추가하려면 파이프라인 객체 에서 $group 연산자 사용합니다.
다음 예시 rated 필드 값을 기준으로 문서를 그룹화하는 파이프라인 단계를 만듭니다. 각 출력 문서 에는 각 그룹의 평점을 저장하는 rating 필드 포함되어 있습니다. 각 출력 문서 에는 그룹 에 있는 모든 영화의 총 런타임을 저장하는 totalRuntime 필드 도 포함되어 있습니다. 그런 다음 이 예시 에서는 집계 파이프라인 실행합니다.
const pipeline = [ { $group: { _id: "$rated", rating: { $first: "$rated" }, totalRuntime: { $sum: "$runtime" } } } ]; const cursor = collection.aggregate(pipeline); return cursor;
자세히 알아보기
The Group and Total Data tutorial provides an extensive example of the $group operator in a common use case.
관련 파이프라인 단계에 대해 자세히 학습 $addFields 가이드 참조하세요.