MongoDB数字字符串排序问题

问题描述

MongoDB中有一个集合t_test_sort结构如下,其中数值字段value为字符串类型,现想按照value的数值大小进行降序排列。

css 复制代码
{
    "_id" : ObjectId("656c87b36ca8100cd4a60348"),
    "name" : "麻了",
    "date" : "2033-04-05",
    "value" : "-1.744353",
    "_class" : "com.rkyao.spring.boot.mongo.entity.MongoSortEntity"
}

使用如下查询语句进行查询,得到的结果显然不对,这样是按照字符串进行排的,而不是数值大小

lua 复制代码
db.getCollection("t_test_sort")
    .find({})
    .sort({ "value": -1 })

尝试解决

网上搜索了一波解决方案都是要添加numericOrdering:true配置,这样可以将字符串按照数值排序,但是试验后依然不行。

lua 复制代码
db.getCollection("t_test_sort")
    .find({})
    .sort({ "value": -1 })
    .collation({"locale": "zh",numericOrdering:true})

百思不得其姐,查询MongoDB官方文档后找到了原因,原来是numericOrdering:true只支持非负整数,负数和小数都不支持

网上的方案行不通,只能继续研究了。

解决方案

方案一

value字段的类型修改为数值型,但是修改字段的影响比较大,需要重新刷数据且有可能会影响其他业务,所以除非走投无路暂不考虑。

方案二

再次查询官方文档后找到了一个方法,可以在聚合管道中使用$toDecimalvalue字段的值转换为数值,赋给一个临时字段sortField,然后在根据sortField字段进行排序。

php 复制代码
db.getCollection("t_test_sort").aggregate([
    {
        $addFields: {
            sortField: { $toDecimal: "$value" }
        }
    },
    {
        $sort: { sortField: -1 }
    }
])

可以看到查询结果完全按照sortField数值大小降序排列,问题解决。

Java代码也一并给出来

csharp 复制代码
public List<MongoSortEntity> sort() {
        List<AggregationOperation> operationList = new ArrayList<>();
        operationList.add(
                Aggregation.project("_id", "name", "date", "value")
                        .and(ConvertOperators.ToDecimal.toDecimal("$value")).as("sortField")
        );
        operationList.add(Aggregation.sort(Sort.by(Sort.Direction.DESC, "sortField")));
        Aggregation aggregation = Aggregation.newAggregation(operationList);
        AggregationResults<MongoSortEntity> results = mongoTemplate.aggregate(aggregation, 't_test_sort', MongoSortEntity.class);
        return results.getMappedResults();
    }

参考文档

numericOrdering用法

www.mongodb.com/docs/manual...

$toDecimal用法

www.mongodb.com/docs/manual...

相关推荐
书中枫叶1 天前
从「上次几点喂奶」到全栈小程序:我做了个喂宝助手
mongodb·微信小程序·node.js
【云轩】1 天前
离散量输入输出电路设计:V/地、V/开、地/开信号与单片机接口的电路实现
单片机·嵌入式硬件·mongodb
冰茶丿1 天前
状态机在嵌入式系统中的应用:不只是switch-case这么简单
数据库·嵌入式硬件·mongodb
2301_768103491 天前
HarmonyOS宠物邻里实战第16篇:寄养申请状态机、记录时间线与回归测试
mongodb·集成测试·express·harmonyos·状态机
没钥匙的锁13 天前
04-Java面向对象基础
java·开发语言·mongodb
喜欢的名字被抢了4 天前
MongoDB生产实践:架构设计、分片集群与运维监控
数据库·mongodb·教程
JSON_L4 天前
MongoDB文档关系详解
数据库·mongodb
葫芦和十三5 天前
图解 MongoDB 30|查询路由与广播查询:带片键定向,不带就广播
后端·mongodb·agent
葫芦和十三5 天前
图解 MongoDB 29|分片键陷阱:jumbo chunk、孤儿文档和写入热点
后端·mongodb·agent
霖霖总总5 天前
[MongoDB小技巧24]MongoDB $lookup 聚合阶段深度解析:从入门到实战
数据库·mongodb