36

mgo做分页的几种方法

 4 years ago
source link: https://www.tuicool.com/articles/FNBnU3U
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

场景

  • 当数据两足够大的时候,一页展示不完的时候,我们经常会需要分页的功能。

方案

方案一,数据不是很大

  • 需要排序
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语言的多线程,可以很快的查询和聚合

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK