Agrupar Dados MongoDB

MongoDBBeginner
Pratique Agora

Introdução

Neste laboratório, você aprenderá os fundamentos da agregação de dados no MongoDB. Você se concentrará em usar o pipeline de agregação para agrupar documentos, realizar cálculos em dados agrupados e, em seguida, filtrar, ordenar e remodelar os resultados. Essas operações são essenciais para análise de dados e relatórios no MongoDB. Ao final deste laboratório, você se sentirá confortável usando o operador $group juntamente com outros estágios de agregação chave para extrair insights significativos de seus dados.

Agrupando Documentos por um Campo

O primeiro passo na agregação de dados é frequentemente agrupar documentos com base em um campo comum. Nesta etapa, você se conectará ao shell do MongoDB, criará um novo banco de dados e coleção e, em seguida, usará o operador $group para agrupar documentos por categoria.

Primeiro, abra o shell do MongoDB executando o seguinte comando no seu terminal:

mongosh

Uma vez dentro do shell, você verá um prompt test>. Vamos mudar para um novo banco de dados chamado salesdb e inserir alguns dados de produtos de exemplo. O MongoDB criará o banco de dados e a coleção automaticamente quando você inserir dados neles pela primeira vez.

Copie e cole os seguintes comandos no shell mongosh:

use salesdb
db.products.insertMany([
  { category: "Electronics", brand: "Apple", price: 1200 },
  { category: "Electronics", brand: "Samsung", price: 800 },
  { category: "Electronics", brand: "Sony", price: 950 },
  { category: "Apparel", brand: "Nike", price: 150 },
  { category: "Apparel", brand: "Adidas", price: 120 },
  { category: "Books", brand: "Penguin", price: 25 },
  { category: "Books", brand: "Penguin", price: 35 }
]);

Agora que você tem os dados, pode realizar uma agregação. O comando a seguir agrupa os documentos pelo campo category e calcula o preço total para cada categoria usando o acumulador $sum.

db.products.aggregate([
  {
    $group: {
      _id: "$category",
      totalPrice: { $sum: "$price" }
    }
  }
]);

Exemplo de Saída:

[
  { "_id": "Books", "totalPrice": 60 },
  { "_id": "Apparel", "totalPrice": 270 },
  { "_id": "Electronics", "totalPrice": 2950 }
]

Vamos detalhar a etapa de agregação:

  • db.products.aggregate([...]): Este é o método usado para realizar a agregação. Ele recebe um array de estágios, formando um pipeline.
  • $group: Este é o operador de estágio que agrupa os documentos de entrada.
  • _id: "$category": Esta expressão especifica a chave pela qual agrupar. Aqui, agrupamos pelo valor do campo category. O prefixo $ indica um caminho de campo.
  • totalPrice: { $sum: "$price" }: Este é um acumulador. Ele define um novo campo no documento de saída chamado totalPrice. O operador $sum calcula a soma do campo price para todos os documentos do grupo.

Usando Múltiplos Acumuladores

O estágio $group pode computar múltiplas agregações simultaneamente. Você pode calcular médias, encontrar valores mínimos ou máximos e contar itens dentro de cada grupo. Esta etapa demonstra como usar vários acumuladores em um único estágio $group.

Você ainda deve estar no shell mongosh, usando o banco de dados salesdb.

Vamos escrever uma agregação mais complexa que calcula o preço total, o preço médio e a quantidade de produtos para cada categoria.

db.products.aggregate([
  {
    $group: {
      _id: "$category",
      totalPrice: { $sum: "$price" },
      averagePrice: { $avg: "$price" },
      productCount: { $sum: 1 }
    }
  }
]);

Exemplo de Saída:

[
  {
    "_id": "Books",
    "totalPrice": 60,
    "averagePrice": 30,
    "productCount": 2
  },
  {
    "_id": "Apparel",
    "totalPrice": 270,
    "averagePrice": 135,
    "productCount": 2
  },
  {
    "_id": "Electronics",
    "totalPrice": 2950,
    "averagePrice": 983.3333333333334,
    "productCount": 3
  }
]

Aqui estão os novos acumuladores que usamos:

  • averagePrice: { $avg: "$price" }: O operador $avg calcula a média do campo price para todos os documentos do grupo.
  • productCount: { $sum: 1 }: Esta é uma forma comum de contar documentos em um grupo. Para cada documento, ele adiciona 1 à soma, contando efetivamente os documentos.

Filtrando Dados Agrupados

Após agrupar os dados, você frequentemente precisa filtrar os grupos com base nos valores calculados. Por exemplo, você pode querer ver apenas as categorias onde as vendas totais excedem um determinado valor. O estágio $match é usado para este propósito. Ele pode ser colocado após um estágio $group para filtrar os documentos agrupados.

Vamos encontrar as categorias onde o preço total dos produtos é maior que 500.

db.products.aggregate([
  {
    $group: {
      _id: "$category",
      totalPrice: { $sum: "$price" }
    }
  },
  {
    $match: {
      totalPrice: { $gt: 500 }
    }
  }
]);

Exemplo de Saída:

[{ "_id": "Electronics", "totalPrice": 2950 }]

Neste pipeline:

  1. O estágio $group primeiro calcula o totalPrice para cada categoria.
  2. Os documentos de saída do estágio $group são então passados para o estágio $match.
  3. O estágio $match filtra esses documentos, mantendo apenas aqueles onde o campo totalPrice é maior que ($gt) 500.

Isso demonstra o poder do pipeline de agregação, onde a saída de um estágio se torna a entrada para o próximo.

Ordenando Dados Agrupados

Uma vez que você tenha seus dados agrupados e filtrados, o passo final é frequentemente ordená-los. O estágio $sort permite que você ordene os documentos com base em um ou mais campos, seja em ordem ascendente ou descendente.

Vamos agrupar os produtos por categoria, calcular o preço total e, em seguida, ordenar os resultados por totalPrice em ordem decrescente (do maior para o menor).

db.products.aggregate([
  {
    $group: {
      _id: "$category",
      totalPrice: { $sum: "$price" }
    }
  },
  {
    $sort: {
      totalPrice: -1
    }
  }
]);

Exemplo de Saída:

[
  { "_id": "Electronics", "totalPrice": 2950 },
  { "_id": "Apparel", "totalPrice": 270 },
  { "_id": "Books", "totalPrice": 60 }
]

O estágio $sort recebe um documento que especifica os campos pelos quais ordenar e a ordem de classificação:

  • totalPrice: -1: Isso ordena os documentos pelo campo totalPrice. O valor -1 especifica uma ordem decrescente. Para ordenar em ordem ascendente, você usaria 1.

Você também pode ordenar por múltiplos campos. Por exemplo, $sort: { category: 1, totalPrice: -1 } ordenaria primeiro pelo nome da categoria em ordem alfabética e, em seguida, pelo preço total decrescente para categorias com o mesmo nome.

Remodelando a Saída com $project

Às vezes, o formato de saída do estágio $group não é exatamente o que você precisa. Por exemplo, a chave de grupo é nomeada _id por padrão. O estágio $project permite que você remodele os documentos de saída adicionando, removendo ou renomeando campos.

Vamos construir um pipeline que agrupa por categoria, ordena pelo preço total e, em seguida, remodela a saída para ter um nome de campo mais descritivo para a categoria.

db.products.aggregate([
  {
    $group: {
      _id: "$category",
      totalPrice: { $sum: "$price" }
    }
  },
  {
    $sort: {
      totalPrice: -1
    }
  },
  {
    $project: {
      _id: 0,
      category: "$_id",
      total: "$totalPrice"
    }
  }
]);

Exemplo de Saída:

[
  { "category": "Electronics", "total": 2950 },
  { "category": "Apparel", "total": 270 },
  { "category": "Books", "total": 60 }
]

O estágio $project funciona da seguinte forma:

  • _id: 0: Isso exclui o campo _id da saída. Por padrão, _id é sempre incluído, a menos que seja explicitamente excluído.
  • category: "$_id": Isso cria um novo campo chamado category e atribui a ele o valor do campo _id existente.
  • total: "$totalPrice": Isso cria um novo campo chamado total e atribui a ele o valor do campo totalPrice.

Usar $project é uma maneira poderosa de formatar a saída final do seu pipeline de agregação para aplicações ou relatórios.

Resumo

Neste laboratório, você aprendeu a usar o pipeline de agregação do MongoDB para agrupar e analisar dados. Você começou agrupando documentos com o operador $group e calculando somas. Em seguida, expandiu isso usando múltiplos acumuladores como $avg e $sum: 1 para realizar cálculos mais complexos. Você também aprendeu a encadear estágios de agregação, usando $match para filtrar seus resultados agrupados, $sort para ordená-los e $project para remodelar a saída final em um formato limpo e legível. Estas são habilidades fundamentais para qualquer desenvolvedor ou analista de dados que trabalhe com MongoDB.