MongoDB 数据分组

MongoDBMongoDBBeginner
立即练习

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

介绍

在本实验中,你将学习如何在 MongoDB 中执行基本的聚合操作,包括按单个字段分组数据、计算分组总和、统计分组项数、过滤分组以及排序分组结果。这些技能对于数据分析和从 MongoDB 数据中获取洞察至关重要。

本实验涵盖了一系列聚合技术,从按单个字段分组数据开始,逐步扩展到更复杂的操作,如计算平均值、计数和过滤分组。通过本实验的学习,你将深入了解如何利用 MongoDB 的聚合框架来释放数据的潜力。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL mongodb(("MongoDB")) -.-> mongodb/AggregationOperationsGroup(["Aggregation Operations"]) mongodb(("MongoDB")) -.-> mongodb/BasicOperationsGroup(["Basic Operations"]) mongodb(("MongoDB")) -.-> mongodb/QueryOperationsGroup(["Query Operations"]) mongodb/BasicOperationsGroup -.-> mongodb/insert_document("Insert Document") mongodb/QueryOperationsGroup -.-> mongodb/query_with_conditions("Query with Conditions") mongodb/QueryOperationsGroup -.-> mongodb/sort_documents("Sort Documents") mongodb/QueryOperationsGroup -.-> mongodb/project_fields("Project Fields") mongodb/AggregationOperationsGroup -.-> mongodb/group_documents("Group Documents") mongodb/AggregationOperationsGroup -.-> mongodb/aggregate_group_totals("Aggregate Group Totals") subgraph Lab Skills mongodb/insert_document -.-> lab-422083{{"MongoDB 数据分组"}} mongodb/query_with_conditions -.-> lab-422083{{"MongoDB 数据分组"}} mongodb/sort_documents -.-> lab-422083{{"MongoDB 数据分组"}} mongodb/project_fields -.-> lab-422083{{"MongoDB 数据分组"}} mongodb/group_documents -.-> lab-422083{{"MongoDB 数据分组"}} mongodb/aggregate_group_totals -.-> lab-422083{{"MongoDB 数据分组"}} end

按单个字段分组

在这一步中,你将学习如何使用 MongoDB 的聚合框架按单个字段对数据进行分组。分组允许你根据特定字段组织和汇总数据,这对于数据分析至关重要。

首先,让我们启动 MongoDB shell:

mongosh

接下来,我们创建一个示例产品集合来演示分组操作:

use salesdb

db.products.insertMany([
    { category: "Electronics", price: 500 },
    { category: "Clothing", price: 50 },
    { category: "Electronics", price: 300 },
    { category: "Books", price: 25 },
    { category: "Clothing", price: 75 },
    { category: "Books", price: 40 }
])

然后,我们将使用 $group 聚合操作符按产品类别分组,并计算每个类别的总价格:

db.products.aggregate([
  {
    $group: {
      _id: "$category",
      totalPrice: { $sum: "$price" }
    }
  }
]);
示例输出
[
  { _id: 'Electronics', totalPrice: 800 },
  { _id: 'Clothing', totalPrice: 125 },
  { _id: 'Books', totalPrice: 65 }
]

让我们分解一下这个聚合管道:

  • $group:按指定表达式对文档进行分组
  • _id: "$category":指定我们按类别字段进行分组
  • totalPrice: { $sum: "$price" }:计算每个类别的总价格

计算分组总和

在这一步中,我们将扩展之前的分组技能,学习如何使用 MongoDB 的聚合框架计算各种聚合总和。我们将使用多个聚合操作符从产品数据中提取更复杂的洞察。

让我们继续使用在之前步骤中创建的 salesdb 数据库和 products 集合:

// 确保我们在正确的数据库中
use salesdb

我们将探索不同的聚合操作符来计算分组总和:

  1. 计算每个类别的平均价格:
db.products.aggregate([
  {
    $group: {
      _id: "$category",
      averagePrice: { $avg: "$price" }
    }
  }
]);
  1. 查找每个类别中的最高和最低价格:
db.products.aggregate([
  {
    $group: {
      _id: "$category",
      maxPrice: { $max: "$price" },
      minPrice: { $min: "$price" }
    }
  }
]);
  1. 在单个聚合中组合多个计算:
db.products.aggregate([
  {
    $group: {
      _id: "$category",
      totalPrice: { $sum: "$price" },
      averagePrice: { $avg: "$price" },
      productCount: { $sum: 1 }
    }
  }
]);
示例输出
[
  {
    _id: 'Electronics',
    totalPrice: 800,
    averagePrice: 400,
    productCount: 2
  },
  {
    _id: 'Clothing',
    totalPrice: 125,
    averagePrice: 62.5,
    productCount: 2
  },
  {
    _id: 'Books',
    totalPrice: 65,
    averagePrice: 32.5,
    productCount: 2
  }
]

关键聚合操作符解释:

  • $avg:计算数值的平均值
  • $max:查找最大值
  • $min:查找最小值
  • $sum: 1:计算每个组中的文档数量

统计分组项数

在这一步中,我们将探索使用 MongoDB 聚合框架统计分组内项数的不同方法。计数是一项基本操作,可以帮助你理解数据的分布情况。

让我们继续使用 salesdb 数据库:

// 确保我们在正确的数据库中
use salesdb

首先,我们添加更多产品,使计数操作更加有趣:

db.products.insertMany([
  { category: "Electronics", brand: "Apple" },
  { category: "Electronics", brand: "Samsung" },
  { category: "Clothing", brand: "Nike" },
  { category: "Clothing", brand: "Adidas" },
  { category: "Books", brand: "Penguin" },
  { category: "Books", brand: "Oxford" }
]);

现在,让我们以不同的方式统计项数:

  1. 统计每个类别中的产品数量:
db.products.aggregate([
  {
    $group: {
      _id: "$category",
      productCount: { $sum: 1 }
    }
  }
]);
  1. 统计每个类别中的唯一品牌数量:
db.products.aggregate([
  {
    $group: {
      _id: "$category",
      uniqueBrands: { $addToSet: "$brand" }
    }
  }
]);
  1. 统计唯一品牌数量和总产品数量:
db.products.aggregate([
  {
    $group: {
      _id: "$category",
      totalProducts: { $sum: 1 },
      uniqueBrands: { $addToSet: "$brand" },
      brandCount: { $addToSet: "$brand" }
    }
  },
  {
    $project: {
      totalProducts: 1,
      uniqueBrandCount: { $size: "$uniqueBrands" }
    }
  }
]);
示例输出
[
  {
    _id: 'Electronics',
    totalProducts: 4,
    uniqueBrandCount: 2
  },
  {
    _id: 'Clothing',
    totalProducts: 4,
    uniqueBrandCount: 2
  },
  {
    _id: 'Books',
    totalProducts: 4,
    uniqueBrandCount: 2
  }
]

关键聚合操作符解释:

  • $sum: 1:统计每个组中的文档总数
  • $addToSet:创建一个包含唯一值的数组
  • $size:统计数组中的元素数量

过滤分组

在这一步中,我们将学习如何使用 MongoDB 的聚合框架过滤分组。过滤功能允许你专注于分组数据中的特定子集,从而提供更有针对性的洞察。

让我们继续使用 salesdb 数据库:

// 确保我们在正确的数据库中
use salesdb

让我们为现有产品添加一些价格信息,使过滤操作更有意义:

db.products.updateMany(
  { category: "Electronics", brand: "Apple" },
  { $set: { price: 1000 } }
);

db.products.updateMany(
  { category: "Electronics", brand: "Samsung" },
  { $set: { price: 800 } }
);

db.products.updateMany(
  { category: "Clothing", brand: "Nike" },
  { $set: { price: 100 } }
);

db.products.updateMany(
  { category: "Clothing", brand: "Adidas" },
  { $set: { price: 80 } }
);

现在,让我们探索不同的过滤技术:

  1. 过滤包含多个产品的分组:
db.products.aggregate([
  {
    $group: {
      _id: "$category",
      products: { $push: "$brand" },
      productCount: { $sum: 1 }
    }
  },
  {
    $match: {
      productCount: { $gt: 1 }
    }
  }
]);
  1. 过滤总价格超过特定阈值的分组:
db.products.aggregate([
  {
    $group: {
      _id: "$category",
      totalPrice: { $sum: "$price" },
      products: { $push: "$brand" }
    }
  },
  {
    $match: {
      totalPrice: { $gt: 500 }
    }
  }
]);
  1. 使用多个条件进行复杂过滤:
db.products.aggregate([
  {
    $group: {
      _id: "$category",
      totalPrice: { $sum: "$price" },
      avgPrice: { $avg: "$price" },
      brands: { $addToSet: "$brand" }
    }
  },
  {
    $match: {
      totalPrice: { $gt: 500 },
      avgPrice: { $lt: 900 }
    }
  }
]);
示例输出
[
  {
    _id: 'Electronics',
    totalPrice: 1800,
    avgPrice: 900,
    brands: [ 'Apple', 'Samsung' ]
  }
]

关键聚合操作符解释:

  • $match:根据指定条件过滤文档
  • $gt:大于
  • $lt:小于
  • $push:将元素添加到数组中
  • $addToSet:将唯一元素添加到数组中

排序分组结果

在这最后一步中,我们将学习如何使用 MongoDB 的聚合框架对分组结果进行排序。排序功能可以帮助你组织和优先处理聚合数据,使其更易于分析和理解。

让我们继续使用 salesdb 数据库:

// 确保我们在正确的数据库中
use salesdb

我们将使用已经创建的产品数据来演示排序技术:

  1. 按总价格降序排序分组:
db.products.aggregate([
  {
    $group: {
      _id: "$category",
      totalPrice: { $sum: "$price" },
      productCount: { $sum: 1 }
    }
  },
  {
    $sort: {
      totalPrice: -1
    }
  }
]);
  1. 按产品数量和总价格排序分组:
db.products.aggregate([
  {
    $group: {
      _id: "$category",
      totalPrice: { $sum: "$price" },
      productCount: { $sum: 1 }
    }
  },
  {
    $sort: {
      productCount: -1,
      totalPrice: 1
    }
  }
]);
  1. 使用多个聚合阶段进行高级排序:
db.products.aggregate([
  {
    $group: {
      _id: "$category",
      totalPrice: { $sum: "$price" },
      avgPrice: { $avg: "$price" },
      brands: { $addToSet: "$brand" }
    }
  },
  {
    $project: {
      category: "$_id",
      totalPrice: 1,
      avgPrice: 1,
      brandCount: { $size: "$brands" }
    }
  },
  {
    $sort: {
      brandCount: -1,
      totalPrice: -1
    }
  }
]);
示例输出
[
  {
    category: 'Electronics',
    totalPrice: 1800,
    avgPrice: 900,
    brandCount: 2
  },
  {
    category: 'Clothing',
    totalPrice: 180,
    avgPrice: 90,
    brandCount: 2
  },
  {
    category: 'Books',
    totalPrice: 0,
    avgPrice: 0,
    brandCount: 2
  }
]

关键聚合操作符解释:

  • $sort:对文档进行排序
    • 1:升序
    • -1:降序
  • $project:重塑文档,允许你包含、排除或转换字段
  • $size:统计数组中的元素数量

总结

在本实验中,你将学习如何使用聚合框架对 MongoDB 数据进行分组。首先,你将通过单个字段(例如产品类别)对数据进行分组,并计算每个组的总价格。接着,你将探索更高级的聚合操作符来计算分组总和,包括平均价格、项数统计,以及对分组结果进行过滤和排序。这些技术对于数据分析和从 MongoDB 数据中获取洞察至关重要。