Spring Pageable Sort结合mongoOperations使用时排序顺序不正确问题
问题根因
你遇到的排序异常是MongoDB默认字符串排序规则导致的:MongoDB默认使用二进制编码对比(基于ASCII值)排序字符串,大写字母的ASCII编码范围为65~90,小写字母的ASCII编码范围为97~122,因此所有大写字母都会排在小写字母之前,才会出现I排在f前面的情况。
解决方案
方案1:查询时指定Collation规则(推荐)
MongoDB 3.4及以上版本支持通过Collation自定义排序规则,可指定区域语言、大小写敏感度等配置,实现符合自然语言习惯的排序,和现有Spring Data MongoDB查询逻辑适配成本极低,修改后的代码如下:
// 构造排序规则:指定中文/英文区域,二级对比强度(忽略大小写、重音差异) Collation collation = Collation.of("zh") .strength(Collation.ComparisonLevel.SECONDARY); return mongoOperations.find(Query.query(criteria) .with(pageable) .collation(collation), // 新增Collation配置 Book.class);
如果你的业务主要是英文内容,也可以把of("zh")改为of("en"),配置不影响原有分页、升降序逻辑的生效。
方案2:给集合设置默认Collation(全局生效)
如果该集合的所有字符串排序都需要使用自然排序规则,可以在创建集合时指定默认Collation,后续所有查询不需要额外加配置就会默认使用该规则排序,示例代码如下:
mongoTemplate.createCollection(Book.class, CollectionOptions.empty() .collation(Collation.of("zh").strength(Collation.ComparisonLevel.SECONDARY)));
方案3:内存排序(仅适合小数据量场景)
如果数据量极小,也可以在查询到全量数据后,使用Java自带的字符串自然排序规则在内存中排序后再分页,该方案不需要修改数据库配置,但数据量超过千级时性能会大幅下降,且分页逻辑需要自行实现,不推荐生产环境使用。
内容的提问来源于stack exchange,提问作者Mykola
相关产品推荐
相关产品推荐

