mongotemplate 支持通过 basicquery + org.bson.document.class 直接查询原始 bson 文档,或用 execute 获取原生 mongocollection 绕过映射,也可用 map 作轻量通用载体,但需注意类型选择、聚合兼容性及写操作限制。

Spring Data MongoDB 的 MongoTemplate 本身不直接支持泛型 Document 类型的查询(比如 Document.class),因为 Document 是 MongoDB Java 驱动原生类,而 MongoTemplate 默认依赖 Spring 的类型转换机制(如 MappingMongoConverter)将结果映射为 Java 实体类。但你可以通过几种方式安全、灵活地处理“泛型文档”场景——即不预定义实体类,而是以 org.bson.Document 或 org.springframework.data.mongodb.core.Document 形式读取原始数据。
用 BasicQuery + Document 作为目标类型
这是最直接的方式:跳过 Spring 的对象映射,让 MongoTemplate 返回原始 BSON 文档。
- 导入驱动原生
org.bson.Document(推荐,与 MongoDB Java Driver 一致) - 使用
BasicQuery构造 JSON 字符串或直接传Document作为查询条件 - 调用
find()时指定目标类型为org.bson.Document.class
示例:
import org.bson.Document;
import org.springframework.data.mongodb.core.query.BasicQuery;
// 查询所有匹配文档,返回原始 BSON Document 列表
BasicQuery query = new BasicQuery("{ 'status': { $in: ['active', 'pending'] } }");
List<document> results = mongoTemplate.find(query, Document.class, "orders");
// 也可用 Criteria 构建,再转 BasicQuery
Criteria criteria = Criteria.where("amount").gt(100.0);
BasicQuery basicQuery = new BasicQuery(criteria.getCriteriaObject());
List<document> docs = mongoTemplate.find(basicQuery, Document.class, "orders");
</document></document>
禁用类型转换,避免 MappingMongoConverter 干预
默认情况下,MongoTemplate 会尝试将 Document 反序列化为实体类字段,可能引发 IllegalArgumentException 或字段丢失。若你明确只想拿到原始结构,可临时绕过转换器:
- 不使用
find(Query, Class),改用底层execute回调获取原生MongoCollection - 直接调用
collection.find().into(new ArrayList()),返回Document列表
示例:
mongoTemplate.execute("orders", collection -> {
return collection.find(Filters.gt("createdAt", Instant.now().minusSeconds(3600)))
.into(new ArrayList());
});
这种方式完全脱离 Spring 的映射层,适合动态集合、未知 schema 或调试场景。
配合 Map 作轻量级通用载体
如果你不需要 BSON 特有功能(如 ObjectId、Date 等类型的原生表示),而只是想快速解析成键值结构,可用 Map<string object></string> 替代 Document:
-
Map能被MappingMongoConverter自动识别并填充,兼容性好 - 对嵌套字段、数组、null 值支持稳定,且无需额外依赖 bson 包
- 适合配置类、日志分析、API 中间层等弱类型需求
示例:
Query query = Query.query(Criteria.where("tags").in("urgent", "review"));
List<map object>> maps = mongoTemplate.find(query, Map.class, "logs");
// 可安全 get("message"), get("metadata.user.id") 等
</map>
注意事项与边界情况
使用泛型文档查询时需留意:
-
Document.class必须是org.bson.Document,不是 Spring 的org.springframework.data.mongodb.core.Document(后者已废弃) - 聚合操作(
aggregate)同样支持Document.class,但阶段输出若含计算字段(如$addFields),仍以 BSON 结构返回 - 分页(
Pageable)与Document兼容,但count()需单独调用,因findAndCount()不支持原始类型 - 写操作(insert/update)不建议用
Document作为输入,除非你手动构造完整 BSON 结构(易出错);插入应优先用实体类或Map
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











