大数据MongoDB之mgo驱动如何对查询结果进行排序(正序逆序多字段排序)?

mgo - MongoDB driver for Go,是一个连接数据库的开源工具。
我们要如何使用mgo驱动对查询结果进行排序呢?(正序逆序多字段排序)

文章目录

  1.Sort() 方法
    1.1 可以使用 Sort() 方法根据某个字段进行排序
    1.2 可以逆序查询,只要在字段名前加上 '-' 号就好
    1.3 也可以多字段查询
  2.源码解析


1.Sort() 方法

1.1 可以使用 Sort() 方法根据某个字段进行排序

query1 := collection.Find(nil).Sort("name")
复制代码

结果示例

name time
Caochao 2019
Caochao 2017
Caochao 2018
Liubei 2018
Liubei 2017
Sunquan 2019
Sunquan 2018

Sort() 方法会接收你传入的某个字段,然后向数据库发送排序请求,再接收数据库返回的结果。



1.2 可以逆序查询,只要在字段名前加上 '-' 号就好

query2 := collection.Find(nil).Sort("-name")
复制代码

结果示例

name time
Sunquan 2018
Sunquan 2019
Liubei 2017
Liubei 2018
Caochao 2018
Caochao 2017
Caochao 2019



1.3 也可以多字段查询

字段在前的则是优先排序的,字段在后的就进行二级排序

像下面的就是先根据名称进行排序,再根据时间进行排序。

query1 := collection.Find(nil).Sort("name", "time")
复制代码

结果示例

name time
Caochao 2017
Caochao 2018
Caochao 2019
Liubei 2017
Liubei 2018
Sunquan 2018
Sunquan 2019

2. 源码解析

MongoDB传参的方式是使用参数 1 与 -1 来指定的,如 db.COLLECTION_NAME.find().sort({KEY:1}) 就是根据key字段进行正序排序。而mgo是通过在字段名前加上 '+'-' 符号实现正反排序的操作的,跟我们所熟悉的MongoDB的操作方式不太一样。 mgo是怎么用 '-' 实现正反序这样的效果的?

我们可以看看源码

func (q *Query) Sort(fields ...string) *Query {
   q.m.Lock()
   var order bson.D
   for _, field := range fields {
      n := 1
      var kind string
      if field != "" {
         if field[0] == '$' {
            if c := strings.Index(field, ":"); c > 1 && c < len(field)-1 {
               kind = field[1:c]
               field = field[c+1:]
            }
         }
         switch field[0] {
         case '+':
            field = field[1:]
         case '-':
            n = -1
            field = field[1:]
         }
      }
      if field == "" {
         panic("Sort: empty field name")
      }
      if kind == "textScore" {
         order = append(order, bson.DocElem{Name: field, Value: bson.M{"$meta": kind}})
      } else {
         order = append(order, bson.DocElem{Name: field, Value: n})
      }
   }
   q.op.options.OrderBy = order
   q.op.hasOptions = true
   q.m.Unlock()
   return q
}
复制代码

下面是一些关键点,我挑出来给大家看一下

n := 1

switch field[0] {
case '+':
    field = field[1:]
case '-':
    n = -1
    field = field[1:]
}

order = append(order, bson.DocElem{Name: field, Value: n})
复制代码

他先是默认按照正序排序( n := 1 ),再对传进来的字段名进行筛选。如果字段名前面带有 '-',则识别为逆序排序,最后带上参数 n 向MongoDB发送请求。

从这些关键地方我们可以知道,mgo的底层操作其实也是传 1 与 -1 的参数的。但是它做了更好的封装,让我们使用起来更为简单。

猜你喜欢

转载自juejin.im/post/5c91ffff6fb9a070e0565d42
今日推荐