MongoDB 字段投影

MongoDBMongoDBBeginner
立即练习

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

介绍

在本实验中,你将学习如何在查询文档时使用 MongoDB 的投影(projection)功能来选择和排除特定字段。投影功能允许你控制查询结果中返回哪些字段,从而减少不必要的数据传输并提高查询性能。你将从选择包含字段开始,然后逐步学习如何指定排除字段、混合包含和排除字段、投影嵌套字段以及格式化输出字段。通过本实验,你将深入了解如何在 MongoDB 查询中有效利用投影功能。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL mongodb(("MongoDB")) -.-> mongodb/BasicOperationsGroup(["Basic Operations"]) mongodb(("MongoDB")) -.-> mongodb/QueryOperationsGroup(["Query Operations"]) mongodb(("MongoDB")) -.-> mongodb/DataTypesGroup(["Data Types"]) mongodb(("MongoDB")) -.-> mongodb/ArrayandEmbeddedDocumentsGroup(["Array and Embedded Documents"]) mongodb(("MongoDB")) -.-> mongodb/AggregationOperationsGroup(["Aggregation Operations"]) mongodb/BasicOperationsGroup -.-> mongodb/start_mongodb_shell("Start MongoDB Shell") mongodb/QueryOperationsGroup -.-> mongodb/find_documents("Find Documents") mongodb/QueryOperationsGroup -.-> mongodb/project_fields("Project Fields") mongodb/DataTypesGroup -.-> mongodb/work_with_array_data_types("Work with Array Data Types") mongodb/ArrayandEmbeddedDocumentsGroup -.-> mongodb/query_embedded_documents("Query Embedded Documents") mongodb/AggregationOperationsGroup -.-> mongodb/aggregate_group_totals("Aggregate Group Totals") subgraph Lab Skills mongodb/start_mongodb_shell -.-> lab-422089{{"MongoDB 字段投影"}} mongodb/find_documents -.-> lab-422089{{"MongoDB 字段投影"}} mongodb/project_fields -.-> lab-422089{{"MongoDB 字段投影"}} mongodb/work_with_array_data_types -.-> lab-422089{{"MongoDB 字段投影"}} mongodb/query_embedded_documents -.-> lab-422089{{"MongoDB 字段投影"}} mongodb/aggregate_group_totals -.-> lab-422089{{"MongoDB 字段投影"}} end

选择包含字段

在这一步中,你将学习如何在查询文档时使用 MongoDB 的投影功能来选择特定字段。投影功能允许你精确控制查询结果中返回哪些字段。

首先,让我们启动 MongoDB shell 并创建一个示例集合以便操作:

mongosh

进入 MongoDB shell 后,创建一个数据库并添加一些示例用户文档:

use projectlab_database

db.users.insertMany([
    {
        name: "John Doe",
        age: 30,
        email: "[email protected]",
        city: "New York",
        job: "Software Engineer"
    },
    {
        name: "Jane Smith",
        age: 28,
        email: "[email protected]",
        city: "San Francisco",
        job: "Data Scientist"
    },
    {
        name: "Mike Johnson",
        age: 35,
        email: "[email protected]",
        city: "Chicago",
        job: "Product Manager"
    }
])

现在,让我们使用投影功能来选择特定字段。要包含字段,请在投影文档中使用 1

db.users.find({}, { name: 1, age: 1, _id: 0 });

示例输出:

[
  { name: 'John Doe', age: 30 },
  { name: 'Jane Smith', age: 28 },
  { name: 'Mike Johnson', age: 35 }
]

让我们分解一下投影:

  • { name: 1, age: 1, _id: 0 } 表示:
    • 包含 name 字段
    • 包含 age 字段
    • 显式排除 _id 字段(默认情况下,_id 字段总是返回)

通过使用投影功能,你可以精确控制查询结果中返回哪些字段,从而减少不必要的数据传输并提高查询性能。

指定排除字段

在这一步中,你将学习如何使用投影功能从 MongoDB 查询结果中排除特定字段。这种技术允许你从文档输出中移除不需要的字段。

我们将继续使用上一步中创建的 users 集合。要排除字段,请在投影文档中使用 0

db.users.find({}, { email: 0, city: 0 });

示例输出:

[
  {
    _id: ObjectId("..."),
    name: 'John Doe',
    age: 30,
    job: 'Software Engineer'
  },
  {
    _id: ObjectId("..."),
    name: 'Jane Smith',
    age: 28,
    job: 'Data Scientist'
  },
  {
    _id: ObjectId("..."),
    name: 'Mike Johnson',
    age: 35,
    job: 'Product Manager'
  }
]

需要记住的重要投影规则:

  • 你不能在同一投影中混合使用包含和排除(除了 _id 字段)
  • _id 是唯一一个你可以在包含其他字段的同时显式排除的字段
  • 使用 0 会从查询结果中移除指定的字段

让我们尝试另一个排除多个字段的示例:

db.users.find({}, { email: 0, city: 0, _id: 0 });

此查询将返回不包含 emailcity_id 字段的文档,仅显示 nameagejob 字段。

混合包含与排除

在这一步中,你将学习 MongoDB 投影中混合包含和排除的细微规则。虽然 MongoDB 通常不允许在同一投影中混合包含和排除,但对于 _id 字段有一个特殊的例外。

让我们使用现有的 users 集合来探索这一概念:

首先,尝试一个演示一般规则的示例:

// 这将导致错误
db.users.find({}, { name: 1, email: 0 });

你会看到一个错误消息,表明你不能混合包含和排除投影。

然而,_id 是一个特殊情况。你可以在显式管理 _id 字段的同时包含或排除其他字段:

db.users.find(
  {},
  {
    _id: 0, // 排除 _id
    name: 1, // 包含 name
    job: 1 // 包含 job
  }
);

示例输出:

[
  { name: 'John Doe', job: 'Software Engineer' },
  { name: 'Jane Smith', job: 'Data Scientist' },
  { name: 'Mike Johnson', job: 'Product Manager' }
]

让我们尝试另一个不同组合的示例:

db.users.find(
  {},
  {
    _id: 0, // 排除 _id
    name: 1, // 包含 name
    age: 1, // 包含 age
    email: 0 // 这通常会导致错误,但 _id 的例外允许这样做
  }
);

关键要点:

  • 你不能对常规字段混合使用包含和排除
  • _id 是唯一一个可以在投影其他字段时显式包含或排除的字段
  • 始终明确你想要包含或排除哪些字段

投影嵌套字段

在这一步中,你将学习如何在 MongoDB 文档中投影嵌套字段。嵌套字段是嵌入文档或数组中的字段,投影这些字段需要稍微不同的方法。

首先,让我们更新 users 集合,添加更复杂的嵌套文档:

// 清除现有文档
db.users.deleteMany({});

// 插入带有嵌套结构的文档
db.users.insertMany([
  {
    name: "John Doe",
    contact: {
      email: "[email protected]",
      phone: {
        mobile: "123-456-7890",
        work: "987-654-3210"
      }
    },
    skills: ["JavaScript", "MongoDB", "React"]
  },
  {
    name: "Jane Smith",
    contact: {
      email: "[email protected]",
      phone: {
        mobile: "234-567-8901",
        work: "876-543-2109"
      }
    },
    skills: ["Python", "Data Science", "Machine Learning"]
  }
]);

要投影嵌套字段,请使用点符号(dot notation):

// 投影特定的嵌套字段
db.users.find(
  {},
  {
    name: 1,
    "contact.email": 1,
    "contact.phone.mobile": 1,
    _id: 0
  }
);

示例输出:

[
  {
    name: 'John Doe',
    contact: {
      email: '[email protected]',
      phone: { mobile: '123-456-7890' }
    }
  },
  {
    name: 'Jane Smith',
    contact: {
      email: '[email protected]',
      phone: { mobile: '234-567-8901' }
    }
  }
]

你也可以投影数组字段:

// 投影前两个技能
db.users.find(
  {},
  {
    name: 1,
    skills: { $slice: 2 },
    _id: 0
  }
);

示例输出:

[
  {
    name: 'John Doe',
    skills: ['JavaScript', 'MongoDB']
  },
  {
    name: 'Jane Smith',
    skills: ['Python', 'Data Science']
  }
]

关于嵌套字段投影的关键点:

  • 使用点符号访问嵌套字段
  • 你可以投影深度嵌套的字段
  • 对于数组,你可以使用 $slice 来限制返回的元素数量

格式化输出字段

在这一步中,你将学习如何使用 MongoDB 的投影和聚合技术来格式化和转换输出字段。我们将探索在投影过程中重命名、计算和修改字段的方法。

首先,让我们更新 users 集合,添加更详细的信息:

// 清除现有文档
db.users.deleteMany({});

// 插入包含更复杂数据的文档
db.users.insertMany([
  {
    name: "John Doe",
    age: 30,
    salary: 75000,
    department: "Engineering"
  },
  {
    name: "Jane Smith",
    age: 28,
    salary: 85000,
    department: "Data Science"
  },
  {
    name: "Mike Johnson",
    age: 35,
    salary: 95000,
    department: "Management"
  }
]);

使用 $ 操作符在投影过程中重命名字段:

db.users.find(
  {},
  {
    fullName: "$name",
    yearsOld: "$age",
    annualSalary: "$salary",
    _id: 0
  }
);

示例输出:

[
  { fullName: 'John Doe', yearsOld: 30, annualSalary: 75000 },
  { fullName: 'Jane Smith', yearsOld: 28, annualSalary: 85000 },
  { fullName: 'Mike Johnson', yearsOld: 35, annualSalary: 95000 }
]

你还可以使用 $ 聚合操作符执行计算:

db.users.aggregate([
  {
    $project: {
      name: 1,
      monthlySalary: { $divide: ["$salary", 12] },
      salaryTier: {
        $switch: {
          branches: [
            { case: { $lt: ["$salary", 80000] }, then: "Junior" },
            { case: { $gte: ["$salary", 80000] }, then: "Senior" }
          ],
          default: "Unknown"
        }
      },
      _id: 0
    }
  }
]);

示例输出:

[
  {
    name: 'John Doe',
    monthlySalary: 6250,
    salaryTier: 'Junior'
  },
  {
    name: 'Jane Smith',
    monthlySalary: 7083.333333333333,
    salaryTier: 'Senior'
  },
  {
    name: 'Mike Johnson',
    monthlySalary: 7916.666666666667,
    salaryTier: 'Senior'
  }
]

关于格式化输出字段的关键点:

  • 使用 $ 在投影过程中重命名字段
  • 聚合管道允许复杂的字段转换
  • 你可以执行计算并创建条件字段
  • $project 阶段在字段格式化方面非常强大

总结

在本实验中,你将学习如何使用 MongoDB 的投影功能在查询文档时选择或排除特定字段。你将从仅包含所需字段开始,然后探索排除不需要的字段,最后混合包含和排除以自定义输出。此外,你还将学习如何投影嵌套字段并格式化输出。这些技术使你能够控制查询返回的数据,从而提高性能并减少不必要的数据传输。