Vì bạn có các mảng lồng nhau, bạn cần áp dụng $unwind
toán tử đầu tiên để khử chuẩn hóa các tài liệu nhúng trước khi sử dụng $lookup
đường ống dẫn (trừ khi bạn đã làm phẳng chúng trong hoạt động tổng hợp của mình):
db.personaddress.aggregate([
{ "$unwind": "$address" },
{ "$unwind": "$address.location" },
{
"$lookup": {
"from": "places",
"localField": "address.location.place._id",
"foreignField": "_id",
"as": "address.location.place",
}
}
])
sau đó có thể được triển khai dưới dạng (chưa được kiểm tra):
LookupOperation lookupOperation = LookupOperation.newLookup()
.from("places")
.localField("address.location.place._id")
.foreignField("_id")
.as("address.location.place");
Aggregation agg = newAggregation(
unwind("address"),
unwind("address.location"),
lookupOperation
);
AggregationResults<OutputDocument> aggResults = mongoTemplate.aggregate(
agg, PersonAddressDocument.class, OutputDocument.class
);
Nếu phiên bản Dữ liệu mùa xuân của bạn không hỗ trợ điều này, giải pháp thay thế là triển khai AggregationOperation giao diện để tiếp nhận DBObject
:
public class CustomGroupOperation implements AggregationOperation {
private DBObject operation;
public CustomGroupOperation (DBObject operation) {
this.operation = operation;
}
@Override
public DBObject toDBObject(AggregationOperationContext context) {
return context.getMappedObject(operation);
}
}
Sau đó, triển khai $lookup
hoạt động như một DBObject trong quy trình tổng hợp:
DBObject lookupOperation = (DBObject)new BasicDBObject(
"$lookup", new BasicDBObject("from", "places")
.append("localField", "address.location.place._id")
.append("foreignField", "_id")
.append("as", "address.location.place")
);
sau đó bạn có thể sử dụng làm:
Aggregation agg = newAggregation(
unwind("address"),
unwind("address.location"),
lookupOperation
);
AggregationResults<OutputDocument> aggResults = mongoTemplate.aggregate(
agg, PersonAddressDocument.class, OutputDocument.class
);