MatchOperation matchDepartmentStage = Aggregation.match(Criteria.where("department").is("DEPT_A"));
ProjectionOperation projectEmployeeStage = Aggregation.project()
.andExpression("concat(emp_name,'-', emp_age)").as("emp_name_age");
Criteria criteriaNameAndAge = new Criteria();
List<Pair<String,String>> nameAndAgeList = new ArrayList<>();
nameAndAgeList.add(Pair.of("abcd", "30"));
nameAndAgeList.forEach(nameAndAge -> {
criteriaNameAndAge.and("emp_name_age").ne(nameAndAge.getFirst()+"-"+nameAndAge.getSecond());
});
MatchOperation matchNameAndAgeStage = Aggregation.match(criteriaNameAndAge);
SortOperation sortStage = Aggregation.sort(Sort.Direction.ASC, "dateCreated");
Aggregation aggregation = Aggregation.newAggregation(matchDepartmentStage,
projectEmployeeStage,
matchNameAndAgeStage,
sortStage);
Employee employee = null;
AggregationResults<Employee> employeeAggregationResults =
mongoTemplate.aggregate(aggregation, "employees", Employee.class);
My attempt is to do as following
Filter employees by department
From the result, for every employee, project a new field that combines 2 fields, emp_name & emp_age to emp_name_age
Create a dynamic match criteria to match this new field
Sort by date
It does not work as expected. Error is invalid reference 'dateCreated'
Sample documents:
{ "_id" : "1", "department" : "DEPAT_A", "name" : "abcd", "age" : "30", "dateCreated" : ISODate("2019-12-31T10:30:00Z"), "_class" : "org.example.Employee" }
{ "_id" : "2", "department" : "DEPAT_A", "name" : "abcd", "age" : "40", "dateCreated" : ISODate("2019-12-31T10:30:00Z"), "_class" : "org.example.Employee" }
EDIT
changed a few lines and it is working. 2 problems identified.
Project has to mention the fields. In my case, name all fields, which I didnt like.
Use nin instead of ne
ProjectionOperation projectEmployeeStage = Aggregation.project(Field.fields("department","name","age","dateCreated"))
.andExpression("concat(emp_name,'-', emp_age)").as("emp_name_age");
List<String> nameAges = nameAndAgeList.stream()
.map(nameAge -> nameAge.getFirst()+"-"+nameAge.getSecond())
.collect(Collectors.toList());
Criteria criteriaNameAndAge = new Criteria("emp_name_age").nin(nameAges);
MatchOperation matchNameAndAgeStage = Aggregation.match(criteriaNameAndAge);