介绍
在本实验中,你将学习如何在查询文档时使用 MongoDB 的投影(projection)功能来选择和排除特定字段。投影功能允许你控制查询结果中返回哪些字段,从而减少不必要的数据传输并提高查询性能。你将从选择包含字段开始,然后逐步学习如何指定排除字段、混合包含和排除字段、投影嵌套字段以及格式化输出字段。通过本实验,你将深入了解如何在 MongoDB 查询中有效利用投影功能。
在本实验中,你将学习如何在查询文档时使用 MongoDB 的投影(projection)功能来选择和排除特定字段。投影功能允许你控制查询结果中返回哪些字段,从而减少不必要的数据传输并提高查询性能。你将从选择包含字段开始,然后逐步学习如何指定排除字段、混合包含和排除字段、投影嵌套字段以及格式化输出字段。通过本实验,你将深入了解如何在 MongoDB 查询中有效利用投影功能。
在这一步中,你将学习如何在查询文档时使用 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 });
此查询将返回不包含 email
、city
和 _id
字段的文档,仅显示 name
、age
和 job
字段。
在这一步中,你将学习 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 的投影功能在查询文档时选择或排除特定字段。你将从仅包含所需字段开始,然后探索排除不需要的字段,最后混合包含和排除以自定义输出。此外,你还将学习如何投影嵌套字段并格式化输出。这些技术使你能够控制查询返回的数据,从而提高性能并减少不必要的数据传输。