如何在Spring Data mongoTemplate中实现类SQL嵌套子查询且仅触发1次DB调用
实现方案
你需要使用MongoDB的聚合管道来实现该逻辑,全程仅发起1次数据库请求,等效你给出的SQL嵌套子查询效果,核心逻辑是在服务端一次性完成三层关联匹配,不需要应用端多次请求数据库。
示例代码
import org.springframework.data.mongodb.core.aggregation.Aggregation; import org.springframework.data.mongodb.core.aggregation.LookupOperation; import org.springframework.data.mongodb.core.query.Criteria; import java.util.List; import static org.springframework.data.mongodb.core.aggregation.Aggregation.*; // 构造聚合管道 Aggregation aggregation = newAggregation( // 第一层:匹配libraryId=1的图书馆记录 match(Criteria.where("libraryId").is(1)), // 第二层:关联借阅人集合,匹配对应borrowerId的记录 LookupOperation.newLookup() .from("borrower") .localField("borrowerId") .foreignField("borrowerid") .as("borrowerList"), // 展开借阅人数组,方便后续关联 unwind("borrowerList"), // 第三层:关联图书集合,匹配对应bookId的记录 LookupOperation.newLookup() .from("Book") .localField("borrowerList.bookId") .foreignField("bookId") .as("bookList"), // 展开图书数组 unwind("bookList"), // 将返回根节点替换为图书实体,只保留图书字段 replaceRoot("bookList") ); // 执行查询,仅触发1次数据库调用 List<Book> result = mongoTemplate.aggregate(aggregation, "library", Book.class).getMappedResults();
注意事项
若要进一步优化查询性能,建议给三个集合的关联字段分别创建索引:
library.libraryId、borrower.borrowerid、Book.bookId,可大幅降低关联查询的耗时。
如果你的集合命名、字段命名和示例不一致,对应修改from、localField、foreignField的参数即可。
内容的提问来源于stack exchange,提问作者game wu
相关产品推荐
相关产品推荐

