문서 메뉴

문서 홈애플리케이션 개발MongoDB 매뉴얼

$bucket (aggregation)

이 페이지의 내용

  • 정의
  • 고려 사항
  • 구문
  • 행동
  • 예제
$bucket

지정된 표현식과 버킷 경계를 기반으로 수신 문서를 버킷이라는 그룹으로 분류하고 각 버킷별로 문서를 출력합니다. 각 출력 문서에는 _id 필드가 포함되며, 이 필드의 값은 버킷의 포함 하한을 지정합니다. 출력 옵션은 각 출력 문서에 포함된 필드를 지정합니다.

$bucket 은 입력 문서가 하나 이상 포함된 버킷에 대한 출력 문서만 생성합니다.

$bucket 단계의 RAM 용량은 100 메가바이트로 제한됩니다. 기본적으로 단계가 이 제한을 초과하면 $bucket 에서 오류를 반환합니다. 단계 처리를 위한 더 많은 공간을 확보하려면 allowDiskUse 옵션을 사용하여 집계 파이프라인 단계에서 임시 파일에 데이터를 쓸 수 있도록 설정합니다.

다음도 참조하세요.

{
$bucket: {
groupBy: <expression>,
boundaries: [ <lowerbound1>, <lowerbound2>, ... ],
default: <literal>,
output: {
<output1>: { <$accumulator expression> },
...
<outputN>: { <$accumulator expression> }
}
}
}

$bucket 문서에는 다음 필드가 포함되어 있습니다.

필드
유형
설명
그룹화 기준
표현식

기준별로 문서를 그룹화하는 표현식입니다. 필드 경로를 지정하려면 필드 이름 앞에 $ 달러 기호를 붙이고 따옴표로 묶습니다.

$bucket기본 사양이 포함되어 있지 않은 경우, 각 입력 문서는 groupBy 필드 경로 또는 표현식을 경계에 지정된 범위 중 하나에 속하는 값으로 해석해야 합니다.

배열

각 버킷의 경계를 지정하는 groupBy 표현식을 기반으로 하는 값의 배열입니다. 인접한 각각의 값 쌍은 버킷의 하한 경계(하한값 포함)와 상한 경계(상한값 제외) 역할을 합니다. 경계를 두 개 이상 지정해야 합니다.

지정된 값은 오름차순이어야 하며 모두 동일한 유형이어야 합니다. 단, 값이 다음과 같은 숫자 혼합 형식인 경우는 예외입니다.

[ 10, NumberLong(20), NumberInt(30) ]

예제

[ 0, 5, 10 ] 배열은 다음과 같이 2개의 버킷을 생성합니다.

  • [0, 5)에서 0이 하한값(포함)이며 5가 상한값(제외)입니다.

  • [5, 10)에서 5가 하한값(포함)이며 10이 상한값(제외)입니다.

literal

선택 사항. groupBy 표현식 결과가 경계에 따라 지정된 버킷에 속하지 않는 모든 문서가 포함된 추가 버킷의 _id 를 지정하는 리터럴입니다.

지정되지 않은 경우 각 입력 문서는 groupBy 표현식을 boundaries에 따라 지정된 버킷 범위 중 하나의 값으로 해석해야 하며, 그렇지 않으면 작업에 오류가 발생합니다.

default 값은 가장 낮은 boundaries 값보다 작거나 가장 높은 boundaries 값보다 크거나 같아야 합니다.

default 값은 boundaries의 항목과 다른 유형일 수 있습니다.

문서

선택 사항. _id 필드 외에 출력 문서에 포함할 필드를 지정하는 문서입니다. 포함할 필드를 지정하려면 축적자 표현식을 사용해야 합니다.

<outputfield1>: { <accumulator>: <expression1> },
...
<outputfieldN>: { <accumulator>: <expressionN> }

output 문서를 지정하지 않으면 이 작업은 각 버킷의 문서 수를 포함하는 count 필드를 반환합니다.

output 문서를 지정하면 문서에 지정된 필드만 반환됩니다. 즉, count 필드는 output 문서에 명시적으로 포함되지 않는 한 반환되지 않습니다.

$bucket 은 다음 조건 중 하나 이상을 충족해야 합니다. 그렇지 않으면 작업에 오류가 발생합니다.

  • 각 입력 문서가 그룹화 기준 표현식을 경계에 따라 지정된 버킷 범위 중 하나의 값으로 해석합니다.

  • 값이 를 벗어나거나 groupBy 의 값과 boundaries 다른 BSON 유형 인 버킷 문서에는 기본값 이 boundaries 지정됩니다.

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_namelast_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 }
]
}

$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") }
])

다음 작업은 단계 내에서 두 개의 단계를 사용하여 에 $bucket $facet 의한 그룹화와 에 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" }
]
}
]
}

다음도 참조하세요.

← $addFields (aggregation)