場景
- 當數據兩足夠大的時候,一頁展示不完的時候,我們經常會需要分頁的功能。
方案
方案一,數據不是很大
- 需要排序
s := globalS.Copy()
c := s.DB(db).C(collection)
defer s.Close()
return c.Find(query).Select(selector).Sort(sort).Skip(100).Limit(20).All(result)
這中情況只適用於數據量比較小的時候,當數據量達到一定量,sort會內存益處報錯
方案二,數據比較大
- 不需要排序
s := globalS.Copy()
c := s.DB(db).C(collection)
defer s.Close()
return c.Find(query).Select(selector).Skip(100).Limit(20).All(result)
當數據量比較大的時候,可以使用這種情況。如果需要排序,那就取得返回值後在排序。
方案三,數據比較大,排序
- 需要排序
var result []interface{}
s := globalS.Copy()
c := s.DB(db).C(collection)
defer s.Close()
pipeM := []bson.M{
{"$match": bson.M{"status": "true"}},
{"$skip": start},
{"$limit": end},
{"$sort": bson.M{"height": -1}},
}
pipe := c.Pipe(pipeM)
err = pipe.All(&result)
當數據量比較大的時候,並且需要排序的時候,可以使用這種情況。因爲在skip,limit和sort同時出現的時候,由於有優先級,需要無論順序如何,都是先執行sort,在執行skip,最後執行limit,但是我們使用聚合,也就是mgo裏面的pipeline,可以改變執行的先後順序。
結束語
- 上面的三種情況都不適用大量的數據,首先是skip的限制,有人建議邊查詢邊排序,我沒有嘗試
- 如果數據量過大,我建議使用分庫分表的方式來完成,這樣加上GO語言的多線程,可以很快的查詢和聚合