MongoDB - 投影
MongoDB - 查询中的字段投影
Section titled “MongoDB - 查询中的字段投影”在 MongoDB 中,投影(Projection)是一种机制,用于从文档中仅选择必要的字段,而不是检索整个文档。这是优化性能的关键实践,特别是通过减少网络流量和客户端内存使用。
在 find() 方法中使用投影
Section titled “在 find() 方法中使用投影”find() 方法支持一个投影文档,用于指定要返回的字段。您可以将其作为 find() 的第二个参数传递,或者在现代驱动程序和 shell 中更常见地通过链式调用 .project() 方法。
规则很简单:使用 1 表示包含字段,使用 0 表示排除字段。默认情况下,_id 字段总是包含在内,除非明确排除。
// 现代首选语法,使用 .project()db.COLLECTION_NAME.find({/* query */}).project({/* projection */});
// 传统语法db.COLLECTION_NAME.find({/* query */}, {/* projection */});示例:用户配置文件
Section titled “示例:用户配置文件”考虑一个包含详细用户配置文件的 users 集合:
{ "_id": ObjectId("..."), "username": "alex_doe", "email": "alex.doe@example.com", "profile": { "firstName": "Alex", "lastName": "Doe", "dob": ISODate("1990-05-15T00:00:00Z") }, "loginHistory": [ /* ... 大型数组 ... */ ]}如果我们只需要显示用户名和电子邮件列表,检索庞大的 loginHistory 数组将是浪费的。我们可以使用投影来只获取所需的内容。
// 仅包含 username 和 email,并排除 _iddb.users.find({}).project({ username: 1, email: 1, _id: 0 });结果将如下所示,仅包含投影的字段:
{ "username": "alex_doe", "email": "alex.doe@example.com"}嵌套文档中的字段投影
Section titled “嵌套文档中的字段投影”您可以使用点表示法来投影嵌入文档中的字段。
// 获取用户名和 profile 中的 firstNamedb.users.find({}).project({ username: 1, "profile.firstName": 1, _id: 0});结果:
{ "username": "alex_doe", "profile": { "firstName": "Alex" }}规则和最佳实践
Section titled “规则和最佳实践”- 包含与排除: 您不能在同一个投影中混合使用包含(
1)和排除(0)指定符,只有一个例外:在包含投影中,您始终可以显式排除_id字段(_id: 0)。 _id字段:_id字段默认始终返回。它是您在使用包含投影时唯一可以显式排除的字段。- 性能提升:始终只投影应用程序所需的字段。这可以最大限度地减少网络上的数据传输,并降低应用程序的处理负载。
- 覆盖查询:投影是创建“覆盖查询”的关键。当查询的过滤器和投影可以完全由索引满足时,MongoDB 无需从磁盘读取文档,从而带来巨大的性能提升。要使查询成为覆盖查询,投影中的所有字段都必须是索引的一部分。
一个常见的错误是尝试混合包含和排除。
// 这将导致错误db.users.find({}).project({ username: 1, loginHistory: 0 });
// 错误消息:// "Projection cannot have a mix of inclusion and exclusion"要实现这一点,您必须要么包含除 loginHistory 之外的所有字段,要么排除 loginHistory(这将返回所有其他字段)。