MongoDB 提供了投影(Projection)功能,可以在查询时指定返回哪些字段,从而优化查询性能和减少数据传输量。

方法 1: 使用 find() 的投影参数

// 基本语法:第二个参数为投影对象
// 1 表示包含该字段,0 表示排除该字段
db.collection('yourCollection').find(
  {}, // 查询条件
  { fieldName1: 1, fieldName2: 1 } // 投影:只返回这些字段
)

// 示例:只返回 name 和 email 字段
db.collection('users').find(
  {},
  { name: 1, email: 1 }
)

// 默认情况下 _id 字段总是会返回,如果不需要可以显式排除
db.collection('users').find(
  {},
  { name: 1, email: 1, _id: 0 }
)

方法 2: 使用 projection() 方法

// 使用 projection() 方法链式调用
db.collection('users').find({})
  .projection({ name: 1, email: 1, _id: 0 })
  .toArray()

// 带查询条件的示例
db.collection('users').find({ age: { $gt: 18 } })
  .projection({ name: 1, email: 1 })
  .toArray()

方法 3: 在聚合管道中使用 $project

// 使用聚合管道的 $project 阶段
db.collection('users').aggregate([
  { $match: { age: { $gt: 18 } } },
  { $project: { name: 1, email: 1, _id: 0 } }
])

// $project 还支持更复杂的字段操作
db.collection('users').aggregate([
  {
    $project: {
      fullName: { $concat: ["$firstName", " ", "$lastName"] },
      email: 1,
      _id: 0
    }
  }
])

排除特定字段

// 排除特定字段,返回其他所有字段
db.collection('users').find(
  {},
  { password: 0, secretKey: 0 }
)

// 注意:不能同时使用包含和排除(_id 除外)
// 错误示例:
// db.collection('users').find({}, { name: 1, password: 0 }) // 这会报错

// 正确示例:要么全部包含,要么全部排除
db.collection('users').find({}, { name: 1, email: 1 }) // 只包含
db.collection('users').find({}, { password: 0 }) // 只排除

嵌套字段的投影

// 返回嵌套对象中的特定字段
db.collection('users').find(
  {},
  { "address.city": 1, "address.country": 1, name: 1 }
)

// 返回数组中的特定字段
db.collection('orders').find(
  {},
  { "items.productName": 1, "items.price": 1 }
)

投影的性能优化建议

实用示例组合

// 查询 + 投影 + 排序 + 限制
db.collection('products').find(
  { category: "electronics", price: { $lt: 1000 } },
  { name: 1, price: 1, brand: 1, _id: 0 }
)
  .sort({ price: -1 })
  .limit(10)
  .toArray()

// 统计时只返回需要的字段
db.collection('orders').aggregate([
  { $match: { status: "completed" } },
  { $project: { total: 1, customerId: 1, orderDate: 1 } },
  { $group: { _id: "$customerId", totalSpent: { $sum: "$total" } } }
])