$bucketAuto (agregação)
Nesta página
Definição
$bucketAuto
Categoriza documentos recebidos em um número específico de grupos, chamados blocos, com base em uma expressão especificada. Os limites dos compartimentos são determinados automaticamente em uma tentativa de distribuir uniformemente os documentos no número especificado de compartimentos.
Cada bucket é representado como um documento na saída. O documento para cada bucket contém:
Um objeto
_id
que especifica os limites do bucket.O campo
_id.min
especifica o limite inferior inclusivo para o bucket.O campo
_id.max
especifica o limite superior para o bucket. Esse limite é exclusivo para todos os buckets, exceto para o bucket final da série, onde é inclusivo.
Um campo
count
que contém o número de documentos no bucket. O campocount
é incluído por padrão quando o documentooutput
não é especificado.
O estágio
$bucketAuto
tem a seguinte forma:{ $bucketAuto: { groupBy: <expression>, buckets: <number>, output: { <output1>: { <$accumulator expression> }, ... } granularity: <string> } } CampoTipoDescriçãogroupBy
expressãoUmaexpressão pela qual agrupar documentos. Para especificar um caminho do campo, prefixe o nome do campo com um cifrão$
e coloque-o entre aspas.buckets
inteiroUm número inteiro positivo de 32 bits que especifica o número de buckets nos quais os documentos de entrada são agrupados.output
documentoOpcional. Um documento que especifica os campos a serem incluídos nos documentos de saída, além do campo
_id
. Para especificar o campo a ser incluído, você deve usar expressões accumulator:<outputfield1>: { <accumulator>: <expression1> }, ... O campo
count
padrão não é incluído no documento de saída quandooutput
é especificado. Especifique explicitamente a expressãocount
como parte do documentooutput
para incluí-la:output: { <outputfield1>: { <accumulator>: <expression1> }, ... count: { $sum: 1 } } granularity
stringOpcional. Uma string que especifica a série numérica preferencial usar para garantir que as bordas do limite calculado terminem em números redondos preferenciais ou em suas potências de 10.
Disponível somente se todos os valores de
groupBy
forem numéricos e nenhum deles forNaN
.Os valores suportados de
granularity
são:"R5"
"R10"
"R20"
"R40"
"R80"
"1-2-5"
"E6"
"E12"
"E24"
"E48"
"E96"
"E192"
"POWERSOF2"
Considerações
$bucketAuto
e restrições de memória
O estágio $bucketAuto
tem um limite de 100 megabytes de RAM. Por padrão, se o estágio exceder este limite, $bucketAuto
retornará um erro. Para permitir mais espaço para o processamento do estágio, use a opção allowDiskUse para permitir que os estágios do pipeline de agregação gravem dados em arquivos temporários.
Comportamento
Pode haver menos do que o número especificado de buckets se:
O número de documentos de entrada é menor que o número especificado de buckets.
O número de valores únicos da expressão
groupBy
é menor que o número especificado debuckets
.O
granularity
tem menos intervalos do que o número debuckets
.O
granularity
não é suficiente para distribuir uniformemente os documentos no número especificado debuckets
.
Se a expressão groupBy
se referir a uma array ou documento, os valores serão organizados usando a mesma ordem de $sort
antes de determinar os buckets do intervalo.
A distribuição uniforme de documentos entre buckets depende da cardinalidade, ou do número de valores únicos, do campo groupBy
. Se a cardinalidade não for alta o suficiente, o estágio $bucketAuto pode não distribuir uniformemente os resultados entre os buckets.
Granularidade
O $bucketAuto
aceita um granularity
parâmetro opcional que garante que os limites de todos os buckets sigam uma série de números preferenciais especificada. O uso de uma série numérica preferencial fornece mais controle sobre onde os limites do bucket são definidos entre o intervalo de valores na expressão groupBy
. Eles também podem ser usados para ajudar a definir logaritmicamente e uniformemente os limites do bucket quando o intervalo da expressão groupBy
escala exponencialmente.
Série Renard
As séries de números de Renard são conjuntos de números derivados da 5ª, 10ª ,20ª , 40ª ou 80ª raiz de 10 e, em seguida, incluindo várias potências da raiz que equivalem a valores entre 1,0 a 10,0 (10,3 no caso de R80
).
Configure granularity
para R5
, R10
, R20
, R40
ou R80
para restringir os limites do bucket para valores na série. Os valores da série são multiplicados por uma potência de 10 quando os valores de groupBy
estão fora do intervalo de 1,0 a 10,0 (10,3 para R80
).
Exemplo
A série R5
é baseada na quinta raiz de 10, que é 1,58, e inclui várias potências dessa raiz (arredondada) até que 10 seja atingida. A série R5
é derivada da seguinte forma:
10 0/5 = 1
10 1/5 = 1.584 ~ 1.6
10 2/5 = 2.511 ~ 2.5
10 3/5 = 3.981 ~ 4.0
10 4/5 = 6.309 ~ 6.3
10 5/5 = 10
A mesma abordagem é aplicada à outra série Renard para oferecer granularidade mais fina, ou seja, mais intervalos entre 1,0 e 10,0 (10,3 para R80
).
Série E
A série de números E é semelhante à série Renard, pois subdivide o intervalo de 1.0 a 10.0 por 6 , 12 , 24 , 48 , 96 }, ou 192 nd raiz de dez com um erro relativo específico.
Configure granularity
para E6
, E12
, E24
, E48
, E96
ou E192
para restringir os limites do bucket para valores na série. Os valores da série são multiplicados por uma potência de 10 quando os valores groupBy
estão fora do 1.0 a 10.0 faixa. Para saber mais sobre a série E e seus respectivos erros relativos, consulte série de números preferenciais.
Série 1-2-5
A série 1-2-5
se comporta como uma série Renard de três valores, se essa série existisse.
Defina granularity
para 1-2-5
para restringir os limites do bucket a vários poderes da terceira raiz de 10, arredondada para um dígito significativo.
Exemplo
Os seguintes valores são parte da série 1-2-5
: 0,1, 0,2, 0,5, 1, 2, 5, 10, 20, 50, 100, 200, 500, 1000 e assim por diante...
Poderes de Duas Séries
Defina granularity
como POWERSOF2
para restringir os limites do bucket a números que são uma potência de dois.
Exemplo
Os números a seguir estão de acordo com a potência de duas séries:
2 0 = 1
2 1 = 2
2 2 = 4
2 3 = 8
2 4 = 16
2 5 = 32
e assim por diante...
Uma implementação comum é como vários componentes do computador, como memória, geralmente aderem ao definir POWERSOF2
de números preferenciais:
1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, and so on....
Comparação de diferentes granularidades
A operação a seguir demonstra como a especificação de valores diferentes para granularity
afeta o modo como $bucketAuto
determina os limites do bucket. Uma coleção de things
tem um _id
numerado de 0 a 99:
{ _id: 0 } { _id: 1 } ... { _id: 99 }
Valores diferentes para granularity
são substituídos na seguinte operação:
db.things.aggregate( [ { $bucketAuto: { groupBy: "$_id", buckets: 5, granularity: <granularity> } } ] )
Os resultados na tabela a seguir demonstram como valores diferentes para granularity
geram limites de bucket diferentes:
Granularidade | Resultados | Notas |
---|---|---|
Sem granularidade | { "_id" : { "min" : 0, "max" : 20 }, "count" : 20 } { "_id" : { "min" : 20, "max" : 40 }, "count" : 20 } { "_id" : { "min" : 40, "max" : 60 }, "count" : 20 } { "_id" : { "min" : 60, "max" : 80 }, "count" : 20 } { "_id" : { "min" : 80, "max" : 99 }, "count" : 20 } | |
R20 | { "_id" : { "min" : 0, "max" : 20 }, "count" : 20 } { "_id" : { "min" : 20, "max" : 40 }, "count" : 20 } { "_id" : { "min" : 40, "max" : 63 }, "count" : 23 } { "_id" : { "min" : 63, "max" : 90 }, "count" : 27 } { "_id" : { "min" : 90, "max" : 100 }, "count" : 10 } | |
E24 | { "_id" : { "min" : 0, "max" : 20 }, "count" : 20 } { "_id" : { "min" : 20, "max" : 43 }, "count" : 23 } { "_id" : { "min" : 43, "max" : 68 }, "count" : 25 } { "_id" : { "min" : 68, "max" : 91 }, "count" : 23 } { "_id" : { "min" : 91, "max" : 100 }, "count" : 9 } | |
1-2-5 | { "_id" : { "min" : 0, "max" : 20 }, "count" : 20 } { "_id" : { "min" : 20, "max" : 50 }, "count" : 30 } { "_id" : { "min" : 50, "max" : 100 }, "count" : 50 } | O número especificado de buckets excede o número de faixas na série. |
POTÊNCIAS DE 2 | { "_id" : { "min" : 0, "max" : 32 }, "count" : 32 } { "_id" : { "min" : 32, "max" : 64 }, "count" : 32 } { "_id" : { "min" : 64, "max" : 128 }, "count" : 36 } | O número especificado de buckets excede o número de faixas na série. |
Exemplo
Considere uma coleção artwork
com os seguintes documentos:
{ "_id" : 1, "title" : "The Pillars of Society", "artist" : "Grosz", "year" : 1926, "price" : NumberDecimal("199.99"), "dimensions" : { "height" : 39, "width" : 21, "units" : "in" } } { "_id" : 2, "title" : "Melancholy III", "artist" : "Munch", "year" : 1902, "price" : NumberDecimal("280.00"), "dimensions" : { "height" : 49, "width" : 32, "units" : "in" } } { "_id" : 3, "title" : "Dancer", "artist" : "Miro", "year" : 1925, "price" : NumberDecimal("76.04"), "dimensions" : { "height" : 25, "width" : 20, "units" : "in" } } { "_id" : 4, "title" : "The Great Wave off Kanagawa", "artist" : "Hokusai", "price" : NumberDecimal("167.30"), "dimensions" : { "height" : 24, "width" : 36, "units" : "in" } } { "_id" : 5, "title" : "The Persistence of Memory", "artist" : "Dali", "year" : 1931, "price" : NumberDecimal("483.00"), "dimensions" : { "height" : 20, "width" : 24, "units" : "in" } } { "_id" : 6, "title" : "Composition VII", "artist" : "Kandinsky", "year" : 1913, "price" : NumberDecimal("385.00"), "dimensions" : { "height" : 30, "width" : 46, "units" : "in" } } { "_id" : 7, "title" : "The Scream", "artist" : "Munch", "price" : NumberDecimal("159.00"), "dimensions" : { "height" : 24, "width" : 18, "units" : "in" } } { "_id" : 8, "title" : "Blue Flower", "artist" : "O'Keefe", "year" : 1918, "price" : NumberDecimal("118.42"), "dimensions" : { "height" : 24, "width" : 20, "units" : "in" } }
Agregação única de facet
Na seguinte operação, os documentos de entrada são agrupados em quatro blocos de acordo com os valores no campo price
:
db.artwork.aggregate( [ { $bucketAuto: { groupBy: "$price", buckets: 4 } } ] )
A operação retorna os seguintes documentos:
{ "_id" : { "min" : NumberDecimal("76.04"), "max" : NumberDecimal("159.00") }, "count" : 2 } { "_id" : { "min" : NumberDecimal("159.00"), "max" : NumberDecimal("199.99") }, "count" : 2 } { "_id" : { "min" : NumberDecimal("199.99"), "max" : NumberDecimal("385.00") }, "count" : 2 } { "_id" : { "min" : NumberDecimal("385.00"), "max" : NumberDecimal("483.00") }, "count" : 2 }
Agregação múltipla de facets
O estágio $bucketAuto
pode ser usado dentro do estágio $facet
para processar vários aggregation pipelines no mesmo conjunto de documentos de entrada do artwork
.
O aggregation pipeline a seguir agrupa os documentos da coleção artwork
em buckets com base em price
, year
e area
calculados:
db.artwork.aggregate( [ { $facet: { "price": [ { $bucketAuto: { groupBy: "$price", buckets: 4 } } ], "year": [ { $bucketAuto: { groupBy: "$year", buckets: 3, output: { "count": { $sum: 1 }, "years": { $push: "$year" } } } } ], "area": [ { $bucketAuto: { groupBy: { $multiply: [ "$dimensions.height", "$dimensions.width" ] }, buckets: 4, output: { "count": { $sum: 1 }, "titles": { $push: "$title" } } } } ] } } ] )
A operação retorna o seguinte documento:
{ "area" : [ { "_id" : { "min" : 432, "max" : 500 }, "count" : 3, "titles" : [ "The Scream", "The Persistence of Memory", "Blue Flower" ] }, { "_id" : { "min" : 500, "max" : 864 }, "count" : 2, "titles" : [ "Dancer", "The Pillars of Society" ] }, { "_id" : { "min" : 864, "max" : 1568 }, "count" : 2, "titles" : [ "The Great Wave off Kanagawa", "Composition VII" ] }, { "_id" : { "min" : 1568, "max" : 1568 }, "count" : 1, "titles" : [ "Melancholy III" ] } ], "price" : [ { "_id" : { "min" : NumberDecimal("76.04"), "max" : NumberDecimal("159.00") }, "count" : 2 }, { "_id" : { "min" : NumberDecimal("159.00"), "max" : NumberDecimal("199.99") }, "count" : 2 }, { "_id" : { "min" : NumberDecimal("199.99"), "max" : NumberDecimal("385.00") }, "count" : 2 }, { "_id" : { "min" : NumberDecimal("385.00"), "max" : NumberDecimal("483.00") }, "count" : 2 } ], "year" : [ { "_id" : { "min" : null, "max" : 1913 }, "count" : 3, "years" : [ 1902 ] }, { "_id" : { "min" : 1913, "max" : 1926 }, "count" : 3, "years" : [ 1913, 1918, 1925 ] }, { "_id" : { "min" : 1926, "max" : 1931 }, "count" : 2, "years" : [ 1926, 1931 ] } ] }