Morphia框架按日期排序异常,求正确实现方案
解决Morphia日期排序不正确的问题
哥们,一眼就看出问题所在了——你肯定是把日期以字符串类型存在数据库里了!字符串排序是按字符逐个比较的,而你的日期格式是dd/MM/yyyy HH:mm,排序时会先比较日,再比较月,最后才是年份,这就导致了年份没被正确识别的混乱排序结果。
下面给你两种解决方案,优先推荐第一种长期方案:
方案一:将字段类型改为日期类型(推荐)
这是最根本的解决办法,把实体类中的日期字段从String改成Java的日期类型,Morphia会自动把它存储为MongoDB的Date类型,排序时就会按照日期逻辑处理。
1. 修改实体类字段
比如换成Java 8+的LocalDateTime(推荐,比Date更易用):
import org.mongodb.morphia.annotations.Entity; import org.mongodb.morphia.annotations.Id; import java.time.LocalDateTime; @Entity("your_collection") public class YourDataEntity { @Id private String id; // 替换String为LocalDateTime private LocalDateTime recordDateTime; // 其他业务字段... }
2. 插入数据时转换日期格式
把输入的字符串日期解析成LocalDateTime再存入,避免直接存字符串:
import java.time.format.DateTimeFormatter; // 定义你的日期格式 DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm"); // 解析字符串日期 LocalDateTime date1 = LocalDateTime.parse("19/12/2019 16:11", dateFormatter); LocalDateTime date2 = LocalDateTime.parse("17/12/2018 18:19", dateFormatter); // 赋值给实体并保存 YourDataEntity entity = new YourDataEntity(); entity.setRecordDateTime(date1); datastore.save(entity);
3. 使用Morphia正常排序
现在直接用order方法就能得到正确的日期排序:
// 升序(从旧到新) List<YourDataEntity> sortedAsc = datastore.createQuery(YourDataEntity.class) .order("recordDateTime") .asList(); // 降序(从新到旧) List<YourDataEntity> sortedDesc = datastore.createQuery(YourDataEntity.class) .order("-recordDateTime") .asList();
方案二:临时聚合转换排序(不推荐长期使用)
如果因为历史数据等原因无法修改字段类型,可以用MongoDB的聚合管道,先把字符串日期转换成Date类型再排序,Morphia也支持聚合操作:
import org.mongodb.morphia.aggregation.AggregationPipeline; import static org.mongodb.morphia.aggregation.Projection.*; import static org.mongodb.morphia.aggregation.Sort.*; AggregationPipeline pipeline = datastore.createAggregation(YourDataEntity.class) // 第一步:将字符串日期转换为Date类型 .project( include("otherFields"), // 保留需要的其他字段 projection("convertedDate", convert("$recordDateTime", "date", "dd/MM/yyyy HH:mm")) ) // 第二步:按转换后的日期排序(这里是降序,升序用ascending) .sort(descending("convertedDate")) // 第三步:投影回原实体需要的字段(可选) .project(excludeId(), include("recordDateTime", "otherFields")); // 获取排序结果 List<YourDataEntity> sortedResults = pipeline.asList(YourDataEntity.class);
⚠️ 注意:这个方法每次排序都要做类型转换,性能不如直接用日期字段,只适合临时过渡。
内容的提问来源于stack exchange,提问作者Manoj Majumdar
相关产品推荐
相关产品推荐

