Spring MongoRepository字符串日期列筛选无结果,求解决方案
问题原因
你的MongoDB中存储的是字符串类型的日期(格式如2019-01-01T00:00:00),但查询时使用java.util.Date作为参数,Spring Data MongoDB会自动将Date对象转换为MongoDB的ISODate类型。由于字符串和ISODate属于不同类型,直接对比不会得到预期结果,因此返回0条数据。
解决方法
方法一:转换参数为匹配的字符串格式(无需修改数据结构)
MongoDB对符合ISO 8601格式的日期字符串支持按字典序进行日期比较,只需将查询参数转换成与数据库一致的字符串格式即可:
- 修改Repository方法,将日期参数改为
String类型:
List<YourEntity> findAllByDateAfter(String afterDateStr);
- 调用时将目标日期转换为
yyyy-MM-dd'T'HH:mm:ss格式的字符串:
// 先解析目标日期,再转换为数据库匹配的格式 SimpleDateFormat sourceFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date targetDate = sourceFormat.parse("2022-03-31 23:00:00"); SimpleDateFormat targetFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); String afterDateStr = targetFormat.format(targetDate); List<YourEntity> result = repository.findAllByDateAfter(afterDateStr);
方法二:修改实体类字段类型(推荐长期方案)
如果允许调整数据结构,建议将实体类中的日期字段从String改为Date或Java 8+的LocalDateTime,同时将MongoDB中的数据批量更新为ISODate类型:
- 修改实体类:
import java.util.Date; import org.springframework.data.mongodb.core.mapping.Document; @Document(collection = "your_collection_name") public class YourEntity { private int personId; private Date date; // 替换原String类型的date字段 // 其他字段、Getter、Setter }
- 批量更新MongoDB中的数据(可通过MongoDB Shell执行):
db.your_collection_name.updateMany( { date: { $type: "string" } }, [ { $set: { date: { $dateFromString: { dateString: "$date" } } } } ] )
完成后,原有的findAllByDateAfter(Date date)方法即可正常工作。
方法三:使用MongoTemplate自定义查询
若不想修改Repository或实体类,可通过MongoTemplate编写自定义查询,明确按字符串类型比较:
import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Query; import javax.annotation.Resource; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; // 注入MongoTemplate @Resource private MongoTemplate mongoTemplate; // 查询逻辑 public List<YourEntity> queryDateAfter() throws Exception { Date after = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2022-03-31 23:00:00"); String afterStr = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").format(after); Query query = new Query(Criteria.where("date").gt(afterStr)); return mongoTemplate.find(query, YourEntity.class); }
内容的提问来源于stack exchange,提问作者simplesystems
相关产品推荐
相关产品推荐

