$lookup
構建 simple join 和 let/pipeline 基礎的 LookupSpec、Driver-native 原始階段、unwind 和 lookup count 流程。
localField / foreignField
java
LookupSpec spec = LookupSpec.builder()
.as("orders")
.localField("id")
.foreignField("userId")
.build();let + pipeline + $expr
java
LookupSpec spec = LookupSpec.builder()
.as("orders")
.bindConditionFields("id", eq, "userId")
.bindConditionConst("DONE", eq, "status")
.limit(10)
.sorts(sort -> sort.desc("createdAt"))
.build();• bindConditionFields(leftField, condition, rightField)
• bindConditionFieldsLeftToObjectId(...)
• bindConditionConst, bindConditionBetween, bindConditionLike
• bindConditionExists, bindConditionIsNull, bindConditionIsNotNull
• rawStage(Bson) 用於 Driver-native lookup pipeline 階段
• unwind(preserveNullAndEmptyArrays)
• outerStage(Bson) / outerStages(...) 用於 $lookup 之後的階段
執行 Lookup
java
var left = dsl
.executeEntity(User.class, MongoTemplateName.FRONT)
.fields(pair("status", "ACTIVE"))
.end()
.findAll()
.paging(0, 20);
var right = dsl
.executeEntity(Order.class, MongoTemplateName.FRONT)
.fields(pair("status", "DONE"))
.end()
.findAll();
Flux<ResultTuple<User, List<Order>>> joined =
left.executeLookup(right, spec);unwind(...)를 사용하지 않은 기본 findAll lookup은 right 결과를 List<R>로 반환합니다. 단건 left/right가 필요하면 find().executeLookup(...) 경로를 사용합니다.
Lookup + count / exists
java
Mono<PageResult<ResultTuple<User, List<Order>>>> page =
left.executeLookupAndCount(right, spec);
Mono<ResultTuple<Long, Long>> counts =
leftCount.executeLookup(rightCount, spec);executeLookupAndCount(...) 以 $facet(data, count) 形式同時返回 data 和 totalCount。count/exists builder 也可以將 lookup 結果作為左右 tuple 接收。