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 的引數的。但是它做了更好的封裝,讓我們使用起來更為簡單。