MongoDB

MongoDB 知识量:13 - 42 - 129

6.2 聚合框架进阶><

$project- 6.2.1 -

MongoDB的聚合框架中的$project阶段用于投影,可以选择文档中哪些字段进行操作,或创建新的计算字段。$project接受一个文档,该文档可以指定包含字段、抑制_id字段、添加新字段和重置现有字段的值。或者,可以指定字段的排除。

以下是一些使用$project的示例:

1. 只显示特定的字段:

db.emps.aggregate([  
   { $project: { _id: 0, name: 1 } }  
]).pretty();

上述查询将只显示name字段,并且不显示_id字段。

2. 创建新的计算字段:

db.emps.aggregate([  
   { $project: { _id: 0, name: 1, salaryMultiplier: "$salary" * 1.10 } }  
]).pretty();

上述查询将创建一个新的计算字段salaryMultiplier,它是原始salary字段值的1.1倍。

3. 使用四则运算:

db.emps.aggregate([  
   { $project: { _id: 0, name: 1, salary: 1, totalSalary: { $add: "$salary", 1000 } } }  
]).pretty();

上述查询将计算每个员工的总薪水,即原始薪水加上1000。

$unwind- 6.2.2 -

MongoDB的聚合框架中的$unwind阶段用于展开数组字段。它的作用是将数组字段中的每个元素替换为单独的文档,以便进行后续的处理和转换。

$unwind阶段接受一个参数,该参数是要展开的数组字段的路径。使用$unwind时,数组中的每个元素都会成为输出文档的一部分,而原始文档的其他字段保持不变。

以下是一个使用$unwind的示例:

db.orders.aggregate([  
   { $unwind: "$products" }  
]);

上述查询将展开orders集合中每个文档的products数组字段。每个数组元素都会成为单独的文档,并包含原始文档的其他字段。

需要注意的是,如果数组为空或缺失,$unwind不会输出任何文档。此外,如果数组中有重复的元素,它们会被视为不同的文档输出。

通过结合其他聚合阶段,如$match、$project等,可以进一步过滤、转换和操作展开后的文档。

数组表达式- 6.2.3 -

MongoDB的聚合框架支持多种数组表达式,这些表达式允许对数组字段进行操作和转换。以下是MongoDB聚合框架中常用的数组表达式:

  • $unwind: 用于展开数组字段。它将数组字段中的每个元素替换为单独的文档,以便进行后续的处理和转换。

  • $size: 用于获取数组的长度。它可以用于聚合管道中的计算字段或投影操作。

  • $arrayElemAt: 用于获取数组中指定位置的元素。它接受两个参数:数组字段的路径和要获取的元素的索引位置。

  • $filter: 用于对数组进行过滤,返回符合条件的元素组成的数组。它接受一个过滤器文档作为参数,该文档定义了过滤条件。

  • $concatArrays: 用于将多个数组连接成一个数组。它接受一个数组字段的路径列表作为参数,并返回连接后的数组。

  • $arrayToObject: 用于将数组转换为对象。它接受一个包含键值对的数组作为参数,其中每个键值对表示一个字段名和对应的值。

累加器- 6.2.4 -

MongoDB的聚合框架提供了一些累加器,用于计算聚合管道中的数据。这些累加器可以用于对文档中的数字字段进行求和、平均值、最大值和最小值等计算。

以下是一些常用的累加器:

  • $sum: 用于计算数字字段的总和。它接受一个数字字段的路径作为参数,并将该字段的值相加。

  • $avg: 用于计算数字字段的平均值。它接受一个数字字段的路径作为参数,并将该字段的所有值相加后除以值的数量。

  • $min: 用于找到数字字段的最小值。它接受一个数字字段的路径作为参数,并返回该字段中的最小值。

  • $max: 用于找到数字字段的最大值。它接受一个数字字段的路径作为参数,并返回该字段中的最大值。

这些累加器可以在聚合管道中使用,以对文档中的数字字段进行聚合计算。例如,以下是一个使用$sum累加器的示例:

db.orders.aggregate([  
   {  
      $group: {  
         _id: "$customerId",  
         total: { $sum: "$amount" }  
      }  
   }  
]);

上述查询将按照customerId对orders集合进行分组,并计算每个客户的订单总金额。

分组- 6.2.5 -

MongoDB的聚合框架提供了强大的分组功能,允许根据特定字段对文档进行分组,并对每个组执行聚合操作。

在聚合管道中使用$group阶段可以实现分组。$group阶段接受一个文档,其中包含一个或多个字段路径和一个聚合表达式。聚合表达式可以是累加器(如$sum、$avg、$min、$max等),也可以是其他聚合操作符。

以下是一个使用$group的示例:

db.orders.aggregate([  
   {  
      $group: {  
         _id: "$customerId", // 分组字段  
         total: { $sum: "$amount" } // 累加器表达式  
      }  
   }  
]);

上述查询将按照customerId字段对订单进行分组,并计算每个客户的订单总金额。结果将包含一个_id字段(表示客户ID)和一个total字段(表示订单总金额)。

除了$group阶段,聚合框架还提供了其他分组相关的阶段,如$match、$sort等,以便可以在分组后对结果进行过滤、排序等操作。

投射- 6.2.6 -

在MongoDB的聚合框架中,投射(projection)是一个重要的概念,它允许选择、排除或重命名文档中的字段,以及创建计算字段。投射是通过$project阶段来实现的,该阶段接受一个文档,定义了投射的规则。

投射的基本语法是使用字段名称和值1或0来表示是否包含该字段。字段名称为1表示包含该字段,字段名称为0表示排除该字段。此外,还可以使用表达式来创建计算字段或重命名字段。

以下是一个使用$project进行投射的示例:

db.collection.aggregate([  
   {  
      $project: {  
         _id: 0, // 排除_id字段  
         field1: 1, // 包含field1字段  
         field2: 1, // 包含field2字段  
         calculatedField: { $multiply: ["$field1", "$field2"] } // 创建计算字段  
      }  
   }  
]);

在上面的示例中,$project阶段指定了排除_id字段,包含field1和field2字段,并创建了一个名为calculatedField的计算字段,该字段的值是field1和field2字段的乘积。

除了基本的字段选择和排除,$project还支持各种表达式,如算术运算符、字符串操作、日期操作等。这些表达式允许在聚合管道中进行更复杂的计算和转换。

投射是聚合管道中常用的一个阶段,它可以帮助减少返回的数据量,只获取所需的字段,从而提高查询性能和效率。通过合理地使用投射,可以灵活地处理和转换数据,以满足特定的业务需求。