持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第14天,点击查看活动详情
开发过程中,有些数据可能我们需要手动排序,然而有些数据我们不需要排序,在MongoDB中我们可以增加一个字段(sort)来表示排序。但是这个字段为空,我们正序(ASC)的时候数据却排在最前面。
例如以下查询:
db.collection.find().sort({sort: 1})
得到的结果是:
null
null
1
2
3
我们期望的是:
1
2
3
null
null
这两种结果不同的是null 的位置。
原因
我们先看一下为什么会导致null 排序比较靠前?
因为MongoDB 的是非关系型数据库,在比较时,会先比较数据类型,MongoDB使用以下排序,从低到高:
- 内部类型:
MinKey - 空值:
Null - 数字型:
Numbers(ints、longs、doubles、decimals) - 符号,字符型:
Symbol、String - 对象:
Object - 数组:
Array - 内置
ID:ObjectId - 布尔型:
Boolean - 日期:
Date - 时间戳:
Timestamp - 正则表达式:
Regular Expression - 内部类型:
MaxKey
因为 null > numbers 所以排在前面。
方案
1、调整排序方向
假如我们可以使用倒序来满足我们的需求,我们可以采取倒序排序。
db.collection.find().sort({sort: -1})
2、空值过滤
假如我们不需要返回空值,或者我们可以将非空数据查询出来然后拼接空数据。
db.collection.find({sort: {$exists: true}}).sort({sort: 1})
3、补充默认值
我们可以在插入数据的时候,给数据写入一个最大值。
或者我们可以在查询的时候通过聚合操作补充一个数据
db.collection.aggregate([
{
$project: {
sort: 1,
s: {$ifNull: MaxValue}
}
}
])
但是所有的空值,我们都给赋值了错误的数据,还需要处理。
4、增加字段
我们可以添加一个字段用来标识是否排序
db.collection.find().sort({is_sort: -1, sort: 1})
也可以添加一个反转字段,每次写入都需要将数据反转,然后查询按照反转字段查询,返回按照真实数据返回。
db.collection.find().sort({sort_inverted: -1})
MongoDB在处理空值排序,确实没有关系型那么方便。希望后续可以有优化来处理