6

I am using spring data Mongodb in my project and refer the below classes for my query on grouping the results:

Student class:

@Document(collection = "student")
public class Student {

    @Id
    private String id;

    private String firstName;

    private String lastName;

    //other fields

    //getters & setters

}

StudentResults (dto):

public class StudentResults {

    private String firstName;

    private List<String> studentIds; //I need List<Student> here

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public List<String> getStudentIds() {
        return studentIds;
    }

    public void setStudentIds(List<String> studentIds) {
        this.studentIds = studentIds;
    }
}

StudentServiceImpl class:

public class StudentServiceImpl implements StudentService {
    @Autowired
    private MongoTemplate mongoTemplate;

    public List<StudentResults> findStudentsGroupByFirstName() {
        TypedAggregation<Student> studentAggregation = 
               Aggregation.newAggregation(Student.class,
               Aggregation.group("firstName").
               addToSet("id").as("studentIds"),
               Aggregation.project("studentIds").
               and("firstName").previousOperation());

        AggregationResults<StudentResults> results = mongoTemplate.
             aggregate(studentAggregation, StudentResults.class);

        List<StudentResults> studentResultsList = results.getMappedResults();

        return studentResultsList;
    }
}

Using the above code, I am able to retrieve the List<String> studentIds successfully, but I need to retrieve List<Student> students using Aggregation.group()? Can you help?

1 Answer 1

8

Change your TypedAggregation part to below and add students field to StudentResults

 TypedAggregation<Student> studentAggregation = Aggregation.newAggregation(Student.class,
               Aggregation.group("firstName").
               push("$$ROOT").as("students"));

$$ROOT will push the whole document.

Update:

TypedAggregation<Student> studentAggregation = Aggregation.newAggregation(Student.class,
              Aggregation.group("firstName").
                 push(new BasicDBObject
                       ("_id", "$_id").append
                       ("firstName", "$firstName").append
                       ("lastName", "$lastName")).as("students"));
Sign up to request clarification or add additional context in comments.

6 Comments

Is there any other alternative without using $$ROOT?
okay, thanks, how do I add group by with multiple fields to the above i.e., firstname and lastname?
Np. You can try something like Aggregation.group("firstName", "lastName")
tried push the column , but am getting column value multiple time (which is equal to the number of times in the count) { "group": "[ \"test\" , \"test\" , \"test\"]", "count": 3 }
@Anand Use addToSet for unique values instead of push.
|

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.