Spring MongoRepository获取汇总计数

时间:2018-12-21 01:46:43

标签: spring mongodb mongodb-query spring-data-mongodb

我正在使用spring-data-mongodb 2.0.8版本,我需要获取特定公司部门中的员工人数。下面是等效查询,如果要在MySQL中查询。

MySQL

select 
    departmentId, count(employeeId)
from employees
where companyCode = 'ACME'
group by departmentId

MongoDb

db.employees.aggregate([
    {
      $match: {
        "companyCode": "ACME"
      }
    },
    {
        "$group" : {
            _id:"$departmentId", 
            count:{$sum:1}
        }
    }
])

我的问题是,如何将其转换为类似于JPA的MongoRepository代码。请参见下面的代码:

public interface EmployeeDao extends MongoRepository<Employee, String> {

    Employee findFirstByName(String name);
    Employee findFirstByDepartmentId(String departmentId);
    List<Employee> findEmployeesByCompanyCodeAndDepartmentId(String companyCode, String departmentId);
    List<Employee> findEmployeesByDepartmentId(String departmentId);
    Long countByCompanyCode(String companyCode);
    Long countByDepartmentId(String departmentId);

    // FIXME:
    /*  How will I convert this into MongoRepository code, like above?

        MySQL:
        select 
            departmentId, count(employeeId)
        from employees
        where companyCode = 'ACME'
        group by departmentId

        MongoDb:
        db.employees.aggregate([
            {
              $match: {
                "companyCode": "ACME"
              }
            },
            {
                "$group" : {
                    _id:"$departmentId", 
                    count:{$sum:1}
                }
            }
        ])
    */

}

更新(适用于我的情况)

我发现以下代码适用于我的情况,但是我不确定这是否可以接受或者有很多更好的方法(按照最佳实践)。

...
        String companyCode =  ACME";
        MatchOperation filterCompany = match(new Criteria("companyCode").is(companyCode));
        GroupOperation groupCountByDepartmentId = group("departmentId").count().as("total");
        SortOperation sortByCountDesc = sort(new Sort(Sort.Direction.DESC, "total"));
        ProjectionOperation projectToMatchModel = project()
                .andExpression("_id").as("departmentId")
                .andExpression("total").as("count");
        Aggregation aggregation = Aggregation
                .newAggregation(filterCompany, groupCountByDepartmentId, sortByCountDesc, projectToMatchModel);
        AggregationResults<DepartmentCount> groupResults =
                m_mongoTemplate.aggregate(aggregation, Employee.class, DepartmentCount.class);
        List<DepartmentCount> result = groupResults.getMappedResults();
...

部门数量:

public class DepartmentCount {

    private String departmentId;
    private Integer count;

    // getters and setters

}

谢谢!

1 个答案:

答案 0 :(得分:0)

您可以使用类似于以下内容的AggregationOperations:

ApplicationContext ctx = new AnnotationConfigApplicationContext(MongoConfig.class);
MongoOperations mongoOperation = (MongoOperations) ctx.getBean("mongoTemplate"); 

List<AggregationOperation> aggregationOperations = new ArrayList<AggregationOperation>();
aggregationOperations.add(new MatchOperation(Criteria.where("country").is("tigo")));
aggregationOperations.add(new UnwindOperation(Fields.field("myDetails")));
aggregationOperations.add(new MatchOperation(Criteria.where("myDetails.type").is("health")));
aggregationOperations.add(new SortOperation(new Sort(Sort.Direction.ASC, "myDetails.datetime")));
AggregationResults<AggregateFactoryResult> result = mongoOperation.aggregate(new Aggregation(aggregationOperations), "gui_data", AggregateFactoryResult.class)

请检查this link