Make the MongoDB docs better! We value your opinion. Share your feedback for a chance to win $100.
Click here >
Menu Docs
Página inicial do Docs
/ /

$group (estágio de agregação )

$group

A etapa $group combina múltiplos documentos que possuem os mesmos campos, campo ou expressão em um único documento, conforme uma chave de agrupamento. O resultado é um documento por chave de grupo exclusiva.

Uma chave de grupo geralmente é um campo ou grupo de campos. A chave do grupo também pode ser o resultado de uma expressão. Use o campo _id no estágio de pipeline $group para definir a chave do grupo. Veja abaixo exemplos de uso.

Na saída do estágio $group, o campo _id é definido como a chave de grupo desse documento.

Os documentos de saída também podem conter campos adicionais que são definidos usando expressions acumuladoras.

Observação

$group não ordena seus documentos de saída.

Você pode utilizar o $group para implantações hospedadas nos seguintes ambientes:

  • MongoDB Atlas: o serviço totalmente gerenciado para implantações do MongoDB na nuvem

  • MongoDB Enterprise: a versão autogerenciada e baseada em assinatura do MongoDB

  • MongoDB Community: uma versão com código disponível, de uso gratuito e autogerenciada do MongoDB

O estágio $group tem a seguinte forma de protótipo:

{
$group:
{
_id: <expression>, // Group key
<field1>: { <accumulator1> : <expression1> },
...
}
}
Campo
Descrição

_id

Obrigatório. A expressão _id especifica a chave do grupo. Se você especificar um valor _id nulo ou qualquer outro valor constante, o estágio $group retornará um único documento que agrega valores em todos os documentos de entrada. Veja o exemplo Grupo por Nulo.

field

Opcional. Computado usando os operadores acumulador .

O _id e os operadores acumuladores podem aceitar qualquer expression válido. Para mais informações sobre expressões, consulte Expressões.

$group é um estágio de bloqueio, que faz com que o pipeline espere que todos os dados de entrada sejam recuperados para o estágio de bloqueio antes de processar os dados. Um estágio de bloqueio pode reduzir o desempenho porque reduz o processamento paralelo de um pipeline com vários estágios. Um estágio de bloqueio também pode usar quantidades substanciais de memória para grandes conjuntos de dados.

O operador <accumulator> deve ser um dos seguintes operadores acumuladores:

Nome
Descrição

Retorna o resultado de uma função de acumulador definida pelo usuário.

Retorna uma array de valores de expressão exclusivos para cada grupo. A ordem dos elementos da array é indefinida.

Alterado na versão 5.0: Disponível no estágio $setWindowFields.

Retorna uma média de valores numéricos. Ignora valores não numéricos.

Alterado na versão 5.0: Disponível no estágio $setWindowFields.

Retorna o elemento inferior de um grupo de acordo com a ordem de classificação especificada.

Novidades na versão 5.2.

Disponível nos estágios $group e $setWindowFields.

Retorna uma agregação dos campos n inferiores dentro de um grupo, de acordo com a ordem de classificação especificada.

Novidades na versão 5.2.

Disponível nos estágios $group e $setWindowFields.

Retorna o número de documentos em um grupo.

Diferente do estágio $count do pipeline.

Novidade na versão 5.0: Disponível nos estágios $group e $setWindowFields.

Retorna o resultado de uma expressão para o primeiro documento em um grupo.

Alterado na versão 5.0: Disponível no estágio $setWindowFields.

Retorna uma agregação dos primeiros n elementos dentro de um grupo. Só faz sentido quando os documentos estão em uma ordem definida. Diferente do operador de array $firstN.

Novidade na versão 5.2: Disponível nos estágios $group, expressão e $setWindowFields.

Retorna o resultado de uma expressão para o último documento em um grupo.

Alterado na versão 5.0: Disponível no estágio $setWindowFields.

Retorna uma agregação dos últimos n elementos dentro de um grupo. Só faz sentido quando os documentos estão em uma ordem definida. Diferente do operador de array $lastN.

Novidade na versão 5.2: Disponível nos estágios $group, expressão e $setWindowFields.

Retorna o valor de expressão mais alto para cada grupo.

Alterado na versão 5.0: Disponível no estágio $setWindowFields.

Retorna uma agregação dos n elementos com valor máximo em um grupo. Diferente do operador de array $maxN.

Novidades na versão 5.2.

Disponível em $group, $setWindowFields e como uma expressão.

Retorna uma aproximação da mediana, o 50º percentil, como um valor escalar.

Novidades na versão 7.0.

Este operador está disponível como acumulador nestas etapas:

Também está disponível como uma expressão de agregação.

Retorna um documento criado combinando os documentos de entrada de cada grupo.

Retorna o valor de expressão mais baixo para cada grupo.

Alterado na versão 5.0: Disponível no estágio $setWindowFields.

Retorna uma agregação dos n elementos com valor mínimo em um grupo. Distinto do operador de array $minN .

Novidades na versão 5.2.

Disponível em $group, $setWindowFields e como uma expressão.

Retorna uma array de valores escalares que correspondem aos valores percentuais especificados.

Novidades na versão 7.0.

Este operador está disponível como acumulador nestas etapas:

Também está disponível como uma expressão de agregação.

Retorna uma matriz de valores de expressão para documentos em cada grupo.

Alterado na versão 5.0: Disponível no estágio $setWindowFields.

Retorna o desvio padrão da população dos valores de entrada.

Alterado na versão 5.0: Disponível no estágio $setWindowFields.

Retorna o desvio padrão da amostra dos valores de entrada.

Alterado na versão 5.0: Disponível no estágio $setWindowFields.

Retorna uma soma de valores numéricos. Ignora valores não numéricos.

Alterado na versão 5.0: Disponível no estágio $setWindowFields.

Retorna o principal elemento de um grupo de acordo com a ordem de classificação especificada.

Novidades na versão 5.2.

Disponível nos estágios $group e $setWindowFields.

Retorna uma agregação dos principais campos n dentro de um grupo, de acordo com a ordem de classificação especificada.

Novidades na versão 5.2.

Disponível nos estágios $group e $setWindowFields.

Se o estágio $group exceder 100 megabytes de RAM, o MongoDB gravará os dados em arquivos temporários. No entanto, se a opção allowDiskUse estiver definida como false, $group retornará um erro. Para obter mais informações, consulte Limites do pipeline de agregação.

Esta seção descreve otimizações para melhorar o desempenho de $group. Existem otimizações que você pode fazer manualmente e otimizações que o MongoDB faz internamente.

Se um pipeline sorts e groups pelo mesmo campo e o estágio $group utilizar somente o operador acumulador $first ou $last, considere adicionar um índice no campo agrupado que corresponda à ordem de classificação. Em alguns casos, o estágio $group pode usar o índice para localizar rapidamente o primeiro ou último documento de cada grupo.

Exemplo

Se a coleção movies contiver um índice { year: 1, title: 1 }, o pipeline a seguir poderá usar esse índice para localizar o primeiro documento de cada grupo:

db.movies.aggregate([
{
$sort: { year: 1, title: 1 }
},
{
$group: {
_id: { year: "$year" },
title: { $first: "$title" }
}
}
])

A partir da versão 5.2, O MongoDB utiliza o mecanismo de consulta de execução baseado em slot para executar estágios $group se:

  • $group é o primeiro estágio do pipeline.

  • Todos os estágios anteriores do pipeline também podem ser executados pelo mecanismo de execução baseado em slot.

Para mais informações, consulte Otimização do$group.

Os exemplos nesta página utilizam dados do conjunto de dados de amostra sample_mflix. Para obter detalhes sobre como carregar esse conjunto de dados em sua implantação autogerenciada do MongoDB , consulte Carregar o conjunto de dados de amostra. Se você fez modificações nos bancos de dados de amostra, talvez seja necessário descartar e recriar os bancos de dados para executar os exemplos nesta página.

A operação de agregação a seguir usa o estágio $group para contar o número de documentos na coleção movies:

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

Esta operação de agregação é equivalente à seguinte declaração SQL:

SELECT COUNT(*) AS count FROM movies

Dica

A seguinte operação de agregação utiliza o estágio para recuperar $group os rated valores distintos da movies coleção:

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

Observação

Quando você utiliza $group para recuperar valores distintos em uma coleção fragmentada, se a operação resultar em DISTINCT_SCAN um, o resultado poderá conter documentos órfãos.

O único pipeline semanticamente correto afetado é efetivamente o equivalente lógico de um comando, em que há distinct um $group estágio no início do pipeline ou próximo a ele e o $group não é precedido por um estágio $sort .

Por exemplo, operações $group do seguinte formulário podem resultar em um DISTINCT_SCAN:

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

Para obter mais informações sobre o comportamento de recuperar valores distintos, consulte o comportamento de comando distinto.

Para ver se a sua operação resulta em um,DISTINCT_SCAN verifique os resultados de explicação da sua operação.

A seguinte operação de agregação agrupa documentos pelo campo rated , calculando o tempo de execução total por classificação e retornando apenas as classificações com um tempo de execução total maior ou igual a 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
}
]
Primeiro estágio:
O estágio agrupa os documentos $group por rated para recuperar os valores de classificação distintos. Este estágio retorna totalRuntime para cada grupo de classificação.
Segundo estágio:
O estágio filtra os documentos resultantes para retornar somente classificações $match com totalRuntime maior ou igual 100000 a.

Esta operação de agregação é equivalente à seguinte declaração SQL:

SELECT rated,
Sum(runtime) AS totalRuntime
FROM movies
GROUP BY rated
HAVING totalRuntime >= 100000

Dica

O pipeline a seguir calcula o tempo de execução total, o tempo médio de execução e a contagem de filmes para cada ano anterior a 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 }
]
Primeiro estágio:
O estágio filtra os documentos para passar apenas os filmes lançados antes $match de 1910 para o próximo estágio.
Segundo estágio:
A etapa agrupa os documentos por ano e calcula o tempo de execução total, o tempo médio de execução e a contagem total dos documentos em cada $group grupo.
Terceiro estágio:
O estágio classifica os resultados pelo tempo de execução total para cada grupo em ordem $sort decrescente.

Esta operação de agregação é equivalente à seguinte declaração 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

Dica

A operação de agregação a seguir especifica um grupo _id de null, calculando o tempo de execução total, o tempo médio de execução e a contagem de todos os documentos na coleta.

db.movies.aggregate([
{
$group: {
_id: null,
totalRuntime: { $sum: "$runtime" },
averageRuntime: { $avg: "$runtime" },
count: { $sum: 1 }
}
}
])
[
{
_id: null,
totalRuntime: 2167458,
averageRuntime: 103.65652797704448,
count: 21349
}
]

Esta operação de agregação é equivalente à seguinte declaração SQL:

SELECT Sum(runtime) AS totalRuntime,
Avg(runtime) AS averageRuntime,
Count(*) AS count
FROM movies

Dica

A seguinte operação de agregação dinamiza os dados na coleção movies para agrupar títulos por ano:

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

A seguinte operação de agregação agrupa documentos por ano:

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 }
]
Primeiro estágio:
$match filtra os documentos para passar apenas os filmes lançados antes de 1910 para o próximo estágio.
Segundo estágio:
$group usa a $$ROOT variável de sistema para agrupar os documentos inteiros por ano.
Terceiro estágio:

$addFields adiciona um campo à saída contendo o tempo de execução total de filmes para cada ano.

Observação

Os documentos resultantes não devem exceder o limite de Tamanho do documento BSON de 16 mebibytes.

Quarto estágio:
$sort classifica os documentos resultantes por _id em ordem crescente.

Os exemplos de C# nesta página utilizam o banco de dados sample_mflix a partir dos conjuntos de dados de amostra do Atlas. Para saber como criar um cluster MongoDB Atlas gratuito e carregar os conjuntos de dados de exemplo, consulte Introdução na documentação do driver MongoDB .NET/C#.

A seguinte classe Movie modela os documentos na collection sample_mflix.movies:

public class Movie
{
public ObjectId Id { get; set; }
public int Runtime { get; set; }
public string Title { get; set; }
public string Rated { get; set; }
public List<string> Genres { get; set; }
public string Plot { get; set; }
public ImdbData Imdb { get; set; }
public int Year { get; set; }
public int Index { get; set; }
public string[] Comments { get; set; }
[BsonElement("lastupdated")]
public DateTime LastUpdated { get; set; }
}

Observação

ConventionPack para Pascal Case

As classes C# nesta página usam Pascal case para seus nomes de propriedade, mas os nomes de campo na coleção MongoDB usam Camel case. Para considerar essa diferença, você pode usar o seguinte código para registrar um ConventionPack quando o aplicativo iniciar:

var camelCaseConvention = new ConventionPack { new CamelCaseElementNameConvention() };
ConventionRegistry.Register("CamelCase", camelCaseConvention, type => true);

Para usar o driver MongoDB .NET/C# para adicionar um estágio $group a uma agregação pipeline, chame o método Group() em um objeto PipelineDefinition.

O exemplo a seguir cria um estágio de pipeline que agrupa documentos pelo valor de seu campo Rated. A classificação de cada grupo é mostrada em um campo chamado Rating em cada documento de saída. Cada documento de saída também contém campos chamados TotalRuntime, MedianRuntime e NinetiethPercentileRuntime, que armazenam o total, a mediana e o 90º percentil de tempo de execução para filmes em cada grupo.

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 })
}
);

Os exemplos do Node.js nesta página utilizam o banco de dados do sample_mflix a partir dos conjuntos de dados de amostra do Atlas. Para saber como criar um cluster gratuito do MongoDB Atlas e carregar os conjuntos de dados de exemplo, consulte Introdução na documentação do driver do MongoDB Node.js

Para usar o driver Node.js do MongoDB para adicionar um estágio $group a um pipeline de agregação , use o operador $group em um objeto de pipeline.

O exemplo a seguir cria um estágio de pipeline que agrupa documentos pelo valor de seu campo rated. Cada documento de saída contém um campo rating que armazena a classificação de cada grupo. Cada documento de saída também contém um campo chamado totalRuntime que armazena o tempo de execução total de todos os filmes do grupo. Em seguida, o exemplo executa o agregação pipeline:

const pipeline = [
{
$group: {
_id: "$rated",
rating: { $first: "$rated" },
totalRuntime: { $sum: "$runtime" }
}
}
];
const cursor = collection.aggregate(pipeline);
return cursor;

O tutorial Grupo e dados totais fornece um exemplo extensivo do operador $group em um caso de uso comum.

Para saber mais sobre os estágios de pipeline relacionados, consulte o guia$addFields.

Voltar

$graphLookup

Receber um selo de habilidade

Domine "Os fundamentos da transformação de dados" gratuitamente!

Saiba mais

Nesta página