MongoDB 简明教程

MongoDB $project

1. $project 阶段简介

$project 阶段用于重新塑造管道中的文档。通过该阶段,你可以指定要传递到下一个阶段的字段,从而减少不必要的数据传输并优化查询性能。

$project 阶段,你可以:

  • 包含特定字段。
  • 排除特定字段(例如隐藏 _id)。
  • 重命名字段。
  • 添加新的派生字段(例如通过计算得出的值)。

1.1 基本字段包含与排除

在投影文档中,你使用 1 来包含一个字段,使用 0 来排除一个字段。

示例

下面的操作将仅返回电影的 title(标题)和 year(年份)字段:

db.movies.aggregate([
  {
    $project: {
      _id: 0,
      title: 1,
      year: 1
    }
  }
])

1.2 _id 字段的特殊性

在 MongoDB 的投影操作中,_id 字段默认是包含在结果中的。如果你不想在输出中看到它,必须明确将其设置为 0

除了 _id 字段外,你不能在同一个 $project 阶段中同时混合使用包含(1)和排除(0)规范。

2. 文档重构进阶

除了基础的可见性控制,$project 还允许你改变文档的结构。

2.1 字段重命名

你可以通过将新字段名赋值为旧字段名的引用(需加 $ 前缀)来重命名字段。

示例

year 字段重命名为 releaseYear

db.movies.aggregate([
  {
    $project: {
      _id: 0,
      title: 1,
      releaseYear: "$year"
    }
  }
])

2.2 添加派生字段与表达式

你可以通过表达式在投影阶段创建全新的字段。这在需要对现有数据进行转换或计算时非常有用。

示例

创建一个名为 hasAwards 的布尔字段,用于标记电影是否有奖项信息:

db.movies.aggregate([
  {
    $project: {
      title: 1,
      hasAwards: { $gt: [ { $size: { $ifNull: [ "$awards", [] ] } }, 0 ] }
    }
  }
])

通过这种方式,你可以灵活地定制输出文档,使其完全符合你前端应用或后续分析阶段的需求。