Skip to content

How to make aggregations with lookups to make joins between collections

kaiso edited this page Jun 17, 2018 · 1 revision

RelMongo | How to make aggregations with lookups to make joins between collections


Note : This feature comes from Spring Data MongoDB framework which is the underlying framework that RelMongo uses

Purpose

When you aure using RelMongo to fetch sub objects from referenced collections you may want in some cases to find parent objects based on a filter on a child object. Another use case is when you want to fetch all the objects using a single query in database to avoid making several queries especially in case of large referenced collections, then you can use MongoDB $aggregation and $lookup facilities to achieve this. In the following example you will understand the use case in an easy way.

Example

Let's say we have two collections "people" and "cars", every person can have one or many cars, using RelMongo you can design that in this way:

  • Car Class
@Document(collection = "cars")
public class Car {
    private ObjectId id;
    private String manufacturer;
    private Color color; 
    ...
  • Person Class
@Document(collection = "people")
public class Person {
    private ObjectId id;
    private String name;
    private String email;
    
    @OneToMany(fetch=FetchType.EAGER)
    @JoinProperty(name="carsrefs")
    private List<Car> cars;
    ...

Then in the PersonRepository you can use aggregation to find all people who have a red car like this:

LookupOperation lookup = LookupOperation.newLookup().from("cars").localField("carsrefs._id").foreignField("_id")
				.as("cars");

		AggregationResults<Person> result = mongoTemplate.aggregate(
				Aggregation.newAggregation(lookup, Aggregation.match(Criteria.where("cars.color").is(Color.RED.toString()))), "people",
				Person.class);

		return result.getMappedResults();

Conclusion

  • This was a simple minimalist example, you can do much more based on your use cases.
  • You can find parent RelMongo objects while filtering on child object properties.
  • To find out more about aggreations see MongoDB and Spring Data MongoDB reference documentations.
  • It may make sense to override findAll default implementation by using lookups in order to fetch all related objects in a single MongoDB aggregation query.