最近在开发中遇到一个mongo查询排序的问题,项目中一些高频访问的热数据是放在mongoDB里的,mongo支持很多像SQL一样的操作比如sort就对应于SQL的order by.

比方我们有一个集合来存放一些书籍信息,集合中有下面这些文档

{
    "_id" : "28041",
    "title" : "Mysql入门",
    "subtitle" : "",
    "author" : "John Joe",
    "cate_id" : "223",
    "list_order" : "10",
}
......

{
    "_id" : "28847",
    "title" : "Node即学即用",
    "subtitle" : "",
    "author" : "Mike Wilson",
    "cate_id" : "223",
    "list_order" : "6",
}

上面集合中的list_order字段是用来控制书籍信息在列表中的现实顺序的,比方要查询cate_id 223下的所有书籍,并且把查询结果按list_order降序排列。

db.book.find({"cate_id" : "223"}).sort({"list_order" : -1});
但查询出来的写过却并不是预想的list_order为10的文档排在前面,结果正好相反。原因就是上面的集合中list_order的字段值都是字符串。

由于平常用Mysql比较多所以在查询时自然想到ORDER BY list_order DESC, 但是MongoDB并不能按照数字来排序字符串字段值,上面的集合中如果通过排序字符串值来得到想要的结果需要在个位数字前面补“0” 01,02,03,04,05,06,07,08,09,10,11 这样才能返回想要的排序结果。

另外也可以将list_order的值存储为整数类型

{
    "_id" : "28847",
    "title" : "Node即学即用",
    "subtitle" : "",
    "author" : "Mike Wilson",
    "cate_id" : "223",
    "list_order" : NumberLong(6),
}

同样能得到倒序排列结果。

推荐采用第二种存储整型数值的方法,另外需要注意一些数据是从Mysql查出然后放到Mongo里去的,Mysql中存储的int字段值查询到程序里会变成数字字符串即 6 ==> "6" 所以才有了上面list_order值为"6"的情况, 所以如果需要保存为整型的数据,在save前都要用(int)来进行类型转换。


Kevin
5k 声望1.5k 粉丝