$bucket (집계)
정의
고려 사항
$bucket
및 메모리 제한
$bucket
단계의 RAM 제한은 100 메가바이트입니다. 기본값 단계가 이 제한을 초과하면 $bucket
에서 오류를 반환합니다. 단계 처리 를 위한 더 많은 공간을 확보하려면 allowDiskUse 옵션을 활성화 집계 파이프라인 단계 에서 임시 파일에 데이터를 쓰기 (write) 수 있도록 설정합니다.
구문
{ $bucket: { groupBy: <expression>, boundaries: [ <lowerbound1>, <lowerbound2>, ... ], default: <literal>, output: { <output1>: { <$accumulator expression> }, ... <outputN>: { <$accumulator expression> } } } }
$bucket
문서에는 다음 필드가 포함되어 있습니다.
필드 | 유형 | 설명 | |||
---|---|---|---|---|---|
표현식 | |||||
배열 | 각 버킷의 경계를 지정하는 groupBy 표현식을 기반으로 하는 값의 배열입니다. 인접한 각각의 값 쌍은 버킷의 하한 경계(하한값 포함)와 상한 경계(상한값 제외) 역할을 합니다. 경계를 두 개 이상 지정해야 합니다. 지정된 값은 오름차순이어야 하며 모두 동일한 유형이어야 합니다. 단, 값이 다음과 같은 숫자 혼합 형식인 경우는 예외입니다.
예를 예시
| ||||
literal | |||||
문서 | 선택 사항.
|
행동
$bucket
은 다음 조건 중 하나 이상을 충족해야 합니다. 그렇지 않으면 작업에 오류가 발생합니다.
groupBy
표현식이 배열이나 문서로 해석되면 $bucket
은 $sort
의 비교 논리를 사용하여 입력 문서를 버킷으로 정렬합니다.
예시
연도별 버킷 및 버킷 결과별 필터링
mongosh
에서 다음 문서를 사용하여 artists
라는 이름의 샘플 컬렉션을 만듭니다.
db.artists.insertMany([ { "_id" : 1, "last_name" : "Bernard", "first_name" : "Emil", "year_born" : 1868, "year_died" : 1941, "nationality" : "France" }, { "_id" : 2, "last_name" : "Rippl-Ronai", "first_name" : "Joszef", "year_born" : 1861, "year_died" : 1927, "nationality" : "Hungary" }, { "_id" : 3, "last_name" : "Ostroumova", "first_name" : "Anna", "year_born" : 1871, "year_died" : 1955, "nationality" : "Russia" }, { "_id" : 4, "last_name" : "Van Gogh", "first_name" : "Vincent", "year_born" : 1853, "year_died" : 1890, "nationality" : "Holland" }, { "_id" : 5, "last_name" : "Maurer", "first_name" : "Alfred", "year_born" : 1868, "year_died" : 1932, "nationality" : "USA" }, { "_id" : 6, "last_name" : "Munch", "first_name" : "Edvard", "year_born" : 1863, "year_died" : 1944, "nationality" : "Norway" }, { "_id" : 7, "last_name" : "Redon", "first_name" : "Odilon", "year_born" : 1840, "year_died" : 1916, "nationality" : "France" }, { "_id" : 8, "last_name" : "Diriks", "first_name" : "Edvard", "year_born" : 1855, "year_died" : 1930, "nationality" : "Norway" } ])
다음 작업은 year_born
필드에 따라 문서를 버킷으로 그룹화하고 버킷에 있는 문서 수를 기준으로 필터링합니다.
db.artists.aggregate( [ // First Stage { $bucket: { groupBy: "$year_born", // Field to group by boundaries: [ 1840, 1850, 1860, 1870, 1880 ], // Boundaries for the buckets default: "Other", // Bucket ID for documents which do not fall into a bucket output: { // Output for each bucket "count": { $sum: 1 }, "artists" : { $push: { "name": { $concat: [ "$first_name", " ", "$last_name"] }, "year_born": "$year_born" } } } } }, // Second Stage { $match: { count: {$gt: 3} } } ] )
- 첫 번째 단계
$bucket
단계에서는year_born
필드에 따라 문서를 버킷으로 그룹화합니다. 버킷의 경계는 다음과 같습니다.[1840, 1850)에서
1840
이 하한값(포함)이며1850
이 상한값(제외)입니다.[1850, 1860)에서
1850
이 하한값(포함)이며1860
이 상한값(제외)입니다.[1860, 1870)에서
1860
이 하한값(포함)이며1870
이 상한값(제외)입니다.[1870, 1880)에서
1870
이 하한값(포함)이며1880
이 상한값(제외)입니다.문서에
year_born
필드가 없거나year_born
필드가 위의 범위를 벗어난 경우,_id
값"Other"
를 사용하여 기본 버킷에 배치됩니다.
이 단계에는 반환할 필드를 결정하는 출력 문서가 포함되어 있습니다.
필드설명_id
버킷의 하한값(포함)입니다.count
버킷에 있는 문서 개수입니다.artists
버킷에 있는 각 아티스트에 대한 정보가 포함된 문서의 배열입니다. 각 문서에 포함된 아티스트 정보:
name
의 연결 문자(즉, 아티스트first_name
및last_name
의$concat
)year_born
이 단계에서는 아래의 문서를 다음 단계로 넘깁니다.
{ "_id" : 1840, "count" : 1, "artists" : [ { "name" : "Odilon Redon", "year_born" : 1840 } ] } { "_id" : 1850, "count" : 2, "artists" : [ { "name" : "Vincent Van Gogh", "year_born" : 1853 }, { "name" : "Edvard Diriks", "year_born" : 1855 } ] } { "_id" : 1860, "count" : 4, "artists" : [ { "name" : "Emil Bernard", "year_born" : 1868 }, { "name" : "Joszef Rippl-Ronai", "year_born" : 1861 }, { "name" : "Alfred Maurer", "year_born" : 1868 }, { "name" : "Edvard Munch", "year_born" : 1863 } ] } { "_id" : 1870, "count" : 1, "artists" : [ { "name" : "Anna Ostroumova", "year_born" : 1871 } ] } - 두 번째 단계
$match
단계는 이전 단계의 출력을 필터링하여 3개 이상의 문서가 포함된 버킷만 반환합니다.연산은 다음 문서를 반환합니다.
{ "_id" : 1860, "count" : 4, "artists" : [ { "name" : "Emil Bernard", "year_born" : 1868 }, { "name" : "Joszef Rippl-Ronai", "year_born" : 1861 }, { "name" : "Alfred Maurer", "year_born" : 1868 }, { "name" : "Edvard Munch", "year_born" : 1863 } ] }
$bucket을 $facet과 함께 사용하여 여러 필드로 버킷 수행
$facet
단계를 사용하여 단일 단계에서 여러 개의 $bucket
집계를 수행할 수 있습니다.
mongosh
에서 다음 문서를 사용하여 artwork
라는 이름의 샘플 컬렉션을 만듭니다.
db.artwork.insertMany([ { "_id" : 1, "title" : "The Pillars of Society", "artist" : "Grosz", "year" : 1926, "price" : NumberDecimal("199.99") }, { "_id" : 2, "title" : "Melancholy III", "artist" : "Munch", "year" : 1902, "price" : NumberDecimal("280.00") }, { "_id" : 3, "title" : "Dancer", "artist" : "Miro", "year" : 1925, "price" : NumberDecimal("76.04") }, { "_id" : 4, "title" : "The Great Wave off Kanagawa", "artist" : "Hokusai", "price" : NumberDecimal("167.30") }, { "_id" : 5, "title" : "The Persistence of Memory", "artist" : "Dali", "year" : 1931, "price" : NumberDecimal("483.00") }, { "_id" : 6, "title" : "Composition VII", "artist" : "Kandinsky", "year" : 1913, "price" : NumberDecimal("385.00") }, { "_id" : 7, "title" : "The Scream", "artist" : "Munch", "year" : 1893 /* No price*/ }, { "_id" : 8, "title" : "Blue Flower", "artist" : "O'Keefe", "year" : 1918, "price" : NumberDecimal("118.42") } ])
다음 작업에서는 $facet
단계 내에서 두 개의 $bucket
단계를 사용하여 2개의 그룹을 만듭니다. 하나는 price
기준 그룹이며 다른 하나는 year
기준 그룹입니다.
db.artwork.aggregate( [ { $facet: { // Top-level $facet stage "price": [ // Output field 1 { $bucket: { groupBy: "$price", // Field to group by boundaries: [ 0, 200, 400 ], // Boundaries for the buckets default: "Other", // Bucket ID for documents which do not fall into a bucket output: { // Output for each bucket "count": { $sum: 1 }, "artwork" : { $push: { "title": "$title", "price": "$price" } }, "averagePrice": { $avg: "$price" } } } } ], "year": [ // Output field 2 { $bucket: { groupBy: "$year", // Field to group by boundaries: [ 1890, 1910, 1920, 1940 ], // Boundaries for the buckets default: "Unknown", // Bucket ID for documents which do not fall into a bucket output: { // Output for each bucket "count": { $sum: 1 }, "artwork": { $push: { "title": "$title", "year": "$year" } } } } } ] } } ] )
- 첫 번째 패싯
첫 번째 패싯은 입력 문서를
price
기준으로 그룹화합니다. 버킷의 경계는 다음과 같습니다.[0, 200)에서
0
이 하한값(포함)이며200
이 상한값(제외)입니다.[200, 400)에서
200
이 하한값(포함)이며400
이 상한값(제외)입니다.'Other'는 가격이 없거나 위 범위를 벗어나는 문서가 포함된
default
버킷입니다.
$bucket
단계에는 반환할 필드를 결정하는 출력 문서가 포함되어 있습니다.필드설명_id
버킷의 하한값(포함)입니다.count
버킷에 있는 문서 개수입니다.artwork
버킷에 있는 각 작품에 대한 정보가 포함된 문서의 배열입니다.averagePrice
$avg
연산자를 사용하여 버킷에 있는 모든 작품의 평균 가격을 표시합니다.- 두 번째 패싯
두 번째 패싯은 입력 문서를
year
기준으로 그룹화합니다. 버킷의 경계는 다음과 같습니다.[1890, 1910)에서
1890
이 하한값(포함)이며1910
이 상한값(제외)입니다.[1910, 1920)에서
1910
이 하한값(포함)이며1920
이 상한값(제외)입니다.[1920, 1940)에서
1910
이 하한값(포함)이며1940
이 상한값(제외)입니다.'Unknown'은 연도가 없거나 위 범위를 벗어나는 문서가 포함된
default
버킷입니다.
$bucket
단계에는 반환할 필드를 결정하는 출력 문서가 포함되어 있습니다.필드설명count
버킷에 있는 문서 개수입니다.artwork
버킷에 있는 각 작품에 대한 정보가 포함된 문서의 배열입니다.- 출력
연산은 다음 문서를 반환합니다.
{ "price" : [ // Output of first facet { "_id" : 0, "count" : 4, "artwork" : [ { "title" : "The Pillars of Society", "price" : NumberDecimal("199.99") }, { "title" : "Dancer", "price" : NumberDecimal("76.04") }, { "title" : "The Great Wave off Kanagawa", "price" : NumberDecimal("167.30") }, { "title" : "Blue Flower", "price" : NumberDecimal("118.42") } ], "averagePrice" : NumberDecimal("140.4375") }, { "_id" : 200, "count" : 2, "artwork" : [ { "title" : "Melancholy III", "price" : NumberDecimal("280.00") }, { "title" : "Composition VII", "price" : NumberDecimal("385.00") } ], "averagePrice" : NumberDecimal("332.50") }, { // Includes documents without prices and prices greater than 400 "_id" : "Other", "count" : 2, "artwork" : [ { "title" : "The Persistence of Memory", "price" : NumberDecimal("483.00") }, { "title" : "The Scream" } ], "averagePrice" : NumberDecimal("483.00") } ], "year" : [ // Output of second facet { "_id" : 1890, "count" : 2, "artwork" : [ { "title" : "Melancholy III", "year" : 1902 }, { "title" : "The Scream", "year" : 1893 } ] }, { "_id" : 1910, "count" : 2, "artwork" : [ { "title" : "Composition VII", "year" : 1913 }, { "title" : "Blue Flower", "year" : 1918 } ] }, { "_id" : 1920, "count" : 3, "artwork" : [ { "title" : "The Pillars of Society", "year" : 1926 }, { "title" : "Dancer", "year" : 1925 }, { "title" : "The Persistence of Memory", "year" : 1931 } ] }, { // Includes documents without a year "_id" : "Unknown", "count" : 1, "artwork" : [ { "title" : "The Great Wave off Kanagawa" } ] } ] }