Spring Mongo Criteria中匹配日期字段月份并分组员工ID
解决方案
1. 匹配注册月份为2的员工
你原代码直接用is("2")匹配日期字段的方式完全错误——数据库中存储的是完整日期时间值,不是单独的月份数字。要提取日期的月份进行比较,需借助MongoDB的$month操作符,结合Spring Data Mongo的Criteria.expr()实现:
修正后的查询代码
public List<Employees> getEmployeesInFebruary() { // 构建条件:提取registrationDate的月份并判断是否等于2 Criteria criteria = Criteria.where("$expr").is( new BasicDBObject("$eq", Arrays.asList(new BasicDBObject("$month", "$registrationDate"), 2)) ); Query query = new Query(criteria); // 注意:方法返回类型是Employees,需传入Employees.class而非Visit.class return mongoTemplate.find(query, Employees.class); }
也可以用聚合查询实现相同效果:
public List<Employees> getEmployeesInFebruary() { Aggregation aggregation = Aggregation.newAggregation( Aggregation.match(Criteria.where("$expr").is( new BasicDBObject("$eq", Arrays.asList(new BasicDBObject("$month", "$registrationDate"), 2)) )) ); AggregationResults<Employees> results = mongoTemplate.aggregate(aggregation, "employees", Employees.class); return results.getMappedResults(); }
2. 对注册日期重复的员工ID进行分组
要按注册日期分组、收集重复日期对应的员工ID,使用Aggregation的分组操作即可:
public List<Map<String, Object>> getGroupedEmployeesByRegistrationDate() { Aggregation aggregation = Aggregation.newAggregation( // 按registrationDate分组,收集对应的员工ID集合 Aggregation.group("registrationDate").addToSet("employeeId").as("employeeIds"), // 过滤出员工数量大于1的分组(即注册日期重复的记录) Aggregation.match(Criteria.where("employeeIds").size(1).not()) ); AggregationResults<Map<String, Object>> results = mongoTemplate.aggregate(aggregation, "employees", Map.class); return results.getMappedResults(); }
关键说明
- 如果数据库中
registrationDate是字符串类型而非日期类型,需先用$toDate转换后再提取月份:Criteria criteria = Criteria.where("$expr").is( new BasicDBObject("$eq", Arrays.asList( new BasicDBObject("$month", new BasicDBObject("$toDate", "$registrationDate")), 2 )) ); - 原代码中
return mongoTemplate.find(query, Visit.class);存在类型不匹配问题,必须改为Employees.class才能和方法返回类型一致。
内容的提问来源于stack exchange,提问作者Janeth Jackson
相关产品推荐
相关产品推荐

