Mongodb $lookup in Spring data mongo
Not every "new" feature makes it immediately into abstraction layers such as spring-mongo.
So instead, all you need do is define a class that uses the AggregationOperation
interface, which will instead take a BSON Object specified directly as it's content:
public class CustomAggregationOperation implements AggregationOperation {
private DBObject operation;
public CustomAggregationOperation (DBObject operation) {
this.operation = operation;
}
@Override
public DBObject toDBObject(AggregationOperationContext context) {
return context.getMappedObject(operation);
}
}
Then you can use in your aggregation like this:
Aggregation aggregation = newAggregation(
match(
Criteria.where("username").is("user001")
),
new CustomAggregationOperation(
new BasicDBObject(
"$lookup",
new BasicDBObject("from", "NewFeedContent")
.append("localField","content.contentId")
.append("foreignField", "_id")
.append("as", "NewFeedContent")
)
)
)
Which shows the custom class mixed with the built in match()
pipeline helper.
All that happens underneath each helper is that they serialize to a BSON representation such as with DBObject
anyway. So the constructor here just takes the object directly, and returns it directly from .toDBObject()
, which is the standard method on the interface that will be called when serializing the pipline contents.
Joining Two Collections with Spring Data MongoDB
Employee Class
class Employee {
private String _id;
private String name;
private String dept_id;
}
Department Class
class Department {
private String _id;
private String dept_name;
}
Employee Result Class
public class EmpDeptResult {
private String _id;
private String name;
private List<Object> departments;
}
EmployeeService Class
public class EmployeeService {
@Autowired
private MongoTemplate mongoTemplate;
private Logger LOGGER = LoggerFactory.getLogger(EmployeeService.class);
public void lookupOperation(){
LookupOperation lookupOperation = LookupOperation.newLookup()
.from("Department")
.localField("dept_id")
.foreignField("_id")
.as("departments");
Aggregation aggregation = Aggregation.newAggregation(Aggregation.match(Criteria.where("_id").is("1")) , lookupOperation);
List<EmpDeptResult> results = mongoTemplate.aggregate(aggregation, "Employee", EmpDeptResult.class).getMappedResults();
LOGGER.info("Obj Size " +results.size());
}
}