
本文介绍在 spring data mongodb 中通过 `@query` 注解精准投影 `_id` 字段,以轻量方式批量获取文档 id 列表,避免加载冗余字段,提升查询性能。
在实际开发中,经常需要仅获取集合中所有文档的 _id(例如用于批量处理、缓存预热或前端分页标识),而非完整实体对象。MongoDB 原生支持字段投影(projection),Spring Data MongoDB 也提供了简洁的集成方式。
✅ 正确做法:使用 @Query + 字段投影
在 MongoRepository 接口中,定义如下方法:
@Repository public interface UserRepository extends MongoRepository{ @Query(value = "{}", fields = "{_id: 1}") List findIds(); }
- value = "{}" 表示匹配全部文档(等价于无条件查询);
- fields = "{_id: 1}" 表示仅返回 _id 字段(1 表示包含,0 表示排除;注意:除 _id 外其他字段默认被排除);
- 返回类型为 List
,Spring 会自动将 _id 映射到实体类的 id 字段(需确保 User 类中 id 字段已正确标注 @Id)。
若你希望直接返回 List
ListuserIds = userRepository.findIds().stream() .map(User::getId) .collect(Collectors.toList());
⚠️ 注意事项
- 不要省略 fields 参数——若只写 @Query("{}"),MongoDB 将返回完整文档,造成不必要的网络与内存开销;
- _id 在 MongoDB 中默认是 ObjectId 类型,若 Java 实体中 id 字段声明为 String,Spring 会自动完成 ObjectId ↔ String 转换(前提是 MongoConfiguration 已启用默认转换器);
- 如需去重或添加条件(如按 color 筛选),可扩展 value 参数:
@Query(value = "{color: 'blue'}", fields = "{_id: 1}") ListfindBlueUserIds();
✅ 替代方案(进阶)
对于纯 ID 列表需求,也可使用聚合管道实现零实体映射:
@Aggregation(pipeline = {
"{ $project: { _id: { $toString: '$_id' } } }",
"{ $group: { _id: null, ids: { $push: '$_id' } } }",
"{ $project: { _id: 0, ids: 1 } }"
})
List但该方式复杂度高,日常推荐优先使用字段投影 + List
总之,合理利用 fields 投影是 MongoDB 查询优化的关键实践之一——小改动,大收益。










