Dado que tiene matrices anidadas, debe aplicar $unwind
operador primero para desnormalizar los documentos incrustados antes de usar $lookup
canalización (a menos que ya los haya aplanado en su operación de agregación):
db.personaddress.aggregate([
{ "$unwind": "$address" },
{ "$unwind": "$address.location" },
{
"$lookup": {
"from": "places",
"localField": "address.location.place._id",
"foreignField": "_id",
"as": "address.location.place",
}
}
])
que luego se puede implementar como (no probado):
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
);
Si su versión de Spring Data no admite esto, una solución consiste en implementar la AggregationOperation interfaz para recibir un 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);
}
}
Luego implemente el $lookup
operación como DBObject en la canalización de agregación:
DBObject lookupOperation = (DBObject)new BasicDBObject(
"$lookup", new BasicDBObject("from", "places")
.append("localField", "address.location.place._id")
.append("foreignField", "_id")
.append("as", "address.location.place")
);
que luego puede usar como:
Aggregation agg = newAggregation(
unwind("address"),
unwind("address.location"),
lookupOperation
);
AggregationResults<OutputDocument> aggResults = mongoTemplate.aggregate(
agg, PersonAddressDocument.class, OutputDocument.class
);