1

I have the following classes

@Document("artists")
public class Artist {
    private String name;
    private List<Album> discography;
    // Getters and Setters
}

public class Album {
    private String title;
    private Instant releaseDate;
    // Getters and Setters
}

My goal is to write an Aggregate function using Spring data mongodb that will allow me to first find an Artist by name, then look through the associated List<Album> and filter its contents based on a date range provided. It should then return a List<Album> with all the instances of Album that fell within that date range.

The main problem I'm having is that an instance of CriteriaDefinition is provided, and I need to construct the Aggregation and $filter conditions using the contents of it.

// A CriteriaDefinition gets passed into this method
// which contains various criteria to search on

Aggregation agg = Aggregation.newAggregation(
    Aggregation.match(criteriaDefinition), //This returns the correct Artist, but with all Album objects
    Aggregation.project()
        .and(filter("album.discography")
        .as("discography")
        .by( //how do use a CriteriaDefinition here? )
    .as("albums")
);

List<Album> albums = mongoTemplate
            .aggregate(agg, Artist.class, Album.class);
return albums;

Is it even possible to filter on CriteriaDefinition?

1 Answer 1

1

You can use unwind operator with a match on subdocuments. For example i filtered artists with name "foobar" and returned its albums with a releaseDate greater than now. Please try :

Aggregation aggregation = newAggregation(
                match(where("name").is("foobar")),
                unwind("discography"),
                match(where("discography.releaseDate").gt(new Date())));

AggregationResults<Album> results = mongoTemplate.aggregate(aggregation, Artist.class, Album.class);
List<Album> albums = results.getMappedResults();
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.