Mongodb如何将值为null的字段通过排序排在最后
回想起来也好长时间没有记录学习了,正好趁着十一假期稍微学习了一下mongoDB,作为有别于关系型数据库的mysql和oracle,mongoDB算是典型的通过数据冗余,以空间来换取时间。只要使用得当可以解决许多在原本关系型数据库中难以解决的问题。
我还处在学习的初期阶段,在排序查询的时候发现和mysql一样,mongoDB也是在原有排序的基础上,会将null值置于最上方,但是实际工作的过程中,类似需要将某个需要排序的字段升序且null置尾的需求其实不在少数,假如说是在mysql中,我们可以选择使用case when then else来解决,相当于写if else,mongoDB是否也可以用这样的思路呢。答案是肯定的,由于我也是学习的初期,接下来的案例仅作为参考,如果各位看官有更好的方式,欢迎提出不同的方案,一起学习一起讨论。
db.testCol.save({
"nickName": "a",
"num":1
});
db.testCol.save({
"nickName": "b",
"num":null
});
db.testCol.save({
"nickName": "c",
"num":2
});
db.testCol.save({
"nickName": "d"
});
db.testCol.find();
这里简单的随手写段执行语句。
可见结果如下:
各位可见,此处有两种情况
一种是我们最常见的老朋友,null值,还有一个N/A是表是该数据在这一列没有数据,这也是有别于我们关系型数据库的一点,在我们的关系型数据库当中,例如mysql,我们都是先要定义好表字段,而mongoDB则没有这一层关系的约束,他存放的是BJSON,有兴趣的朋友可以去了解一下,说白了就是直接将JSON结果当做数据存放,所以在这里展示出来虽然像是一张表,但他其实只是一个展示的视图罢了,是存在其中某条数据,没有我们视图中的字段的情况的。
概况的说就是某个字段,虽然视图中有,但是不是每个数据都有,他就是以N/A展示,然后存入null就是我们老生常谈了,这里不解释。
那么mongoDB当中我们要创建这样的数据,插入操作就像上面我所写的语句那样,请参考。
如果是要将原有的值修改为这两种的话见如下:
db.testCol.save({
"nickName": "b2",
"num":3
});
db.testCol.save({
"nickName": "c2",
"num":4
});
db.testCol.find();
可见,我们先插入b2,c2两条数据
db.testCol.update({nickName:"b2"},{$unset:{"num":""}});
db.testCol.find();
可见B2的该列已经去除,在关系型数据库中相当于删除一列的作用。
db.testCol.find({nickName:"b2"});
直接单独搜索该条数据将会更明显可见
db.testCol.update({nickName:"c2"},{$set:{"num":null}});
db.testCol.find({nickName:"c2"});
而该语句就是我们以前的修改值为null的操作,很常见,不做解释
这里我们尝试将num进行升序排序
db.testCol.find().sort({num:1})
可见结果中虽然num升序排列,但是num不存在和为空的字段被置顶了,前面也说了,我现在要做的是类似mysql中的case when then else。而mongoDB的该操作在聚合操作当中。
db.testCol.aggregate([
{
"$addFields": {
"sort": {
"$cond": {
"if": "$num",
"then": 1,
"else": 2
}
}
}
},
{
"$sort": {
"sort": 1
}
}
])
如果num字段存在,就映射字段sort为1,否则就是2,然后按照映射出来的sort字段升序排列
这是结果:
很成功,但是可以看见sort只是我们帮助排序的映射字段,我们不希望他被返回给我们,所以我们需要隐藏他
db.testCol.aggregate([
{
"$addFields": {
"sort": {
"$cond": {
"if": "$num",
"then": 1,
"else": 2
}
}
}
},
{
"$sort": {
"sort": 1
}
},
{
"$project": {
"sort": 0
}
}
])
欢迎各位提出其他的可能性和想法。