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();

这里简单的随手写段执行语句。

可见结果如下:

mongodb studio 3t 字段不为空判断 mongodb ifnull_字段


各位可见,此处有两种情况

一种是我们最常见的老朋友,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();

mongodb studio 3t 字段不为空判断 mongodb ifnull_数据_02


可见,我们先插入b2,c2两条数据

db.testCol.update({nickName:"b2"},{$unset:{"num":""}});
db.testCol.find();

mongodb studio 3t 字段不为空判断 mongodb ifnull_mongodb_03


可见B2的该列已经去除,在关系型数据库中相当于删除一列的作用。

db.testCol.find({nickName:"b2"});

直接单独搜索该条数据将会更明显可见

mongodb studio 3t 字段不为空判断 mongodb ifnull_字段_04

db.testCol.update({nickName:"c2"},{$set:{"num":null}});
db.testCol.find({nickName:"c2"});

而该语句就是我们以前的修改值为null的操作,很常见,不做解释

mongodb studio 3t 字段不为空判断 mongodb ifnull_数据库_05


这里我们尝试将num进行升序排序

db.testCol.find().sort({num:1})

mongodb studio 3t 字段不为空判断 mongodb ifnull_字段_06


可见结果中虽然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字段升序排列

这是结果:

mongodb studio 3t 字段不为空判断 mongodb ifnull_数据_07


很成功,但是可以看见sort只是我们帮助排序的映射字段,我们不希望他被返回给我们,所以我们需要隐藏他

db.testCol.aggregate([
  {
    "$addFields": {
      "sort": {
        "$cond": {
          "if": "$num",
          "then": 1,
          "else": 2
        }
      }
    }
  },
  {
    "$sort": {
      "sort": 1
    }
  },
  {
    "$project": {
      "sort": 0
    }
  }
])

mongodb studio 3t 字段不为空判断 mongodb ifnull_数据库_08


欢迎各位提出其他的可能性和想法。