如何使用mongodb/mongo-go-driver进行高效分页

_id我在下面的文章中读到,使用 的自然顺序执行分页效率更高,因为 skip 总是从集合的开头开始。

MongoDB 中快速高效的分页

// Page 1

db.students.find().limit(10)


// Page 2

last_id = ...  # logic to get last_id

db.students.find({'_id': {'$gt': last_id}}).limit(10)

但我不知道如何使用mongodb/mongo-go-driver.


浮云间
浏览 252回答 3
3回答

猛跑小猪

你可以创建一个新的函数,不要忘记传递 http.writer 来读取参数。func Pagination(r *http.Request, FindOptions *options.FindOptions) (int64, int64) {    if r.URL.Query().Get("page") != "" && r.URL.Query().Get("limit") != "" {        page, _ := strconv.ParseInt(r.URL.Query().Get("page"), 10, 32)        limit, _ := strconv.ParseInt(r.URL.Query().Get("limit"), 10, 32)        if page == 1 {            FindOptions.SetSkip(0)            FindOptions.SetLimit(limit)            return page, limit        }        FindOptions.SetSkip((page - 1) * limit)        FindOptions.SetLimit(limit)        return page, limit    }    FindOptions.SetSkip(0)    FindOptions.SetLimit(0)    return 0, 0}只是打电话Pagination(r, options)例子options := options.Find()page, limit := parameter.Pagination(r, options)// page, limit as response for header payload

慕慕森

如果不需要分页,则设置 page=0 和 limit=0。func GetUsers (page, limit int) {    filter := bson.D{{}} // selects all documents    options := new(options.FindOptions)    if limit != 0 {        if page == 0 {            page = 1        }        options.SetSkip(int64((page - 1) * limit))        options.SetLimit(int64(limit))    }    cursor, err := mongoCollection.Find(context.TODO(), filter, options)...}

潇潇雨雨

cursor.skip ()方法要求服务器从输入结果集的开头开始扫描,然后才开始返回结果。随着偏移量的增加,cursor.skip() 会变慢。虽然范围查询可以使用索引来避免扫描不需要的文档,但与用于cursor.skip()分页相比,随着偏移量的增加,通常会产生更好的性能。使用当前版本的mongo-go-driver (v0.0.15)。执行分页的示例首先显示最新条目:func Paginate(collection *mongo.Collection, startValue objectid.ObjectID, nPerPage int64) ([]bson.Document, *bson.Value, error) {    // Query range filter using the default indexed _id field.     filter := bson.VC.DocumentFromElements(        bson.EC.SubDocumentFromElements(            "_id",            bson.EC.ObjectID("$gt", startValue),        ),    )    var opts []findopt.Find    opts = append(opts, findopt.Sort(bson.NewDocument(bson.EC.Int32("_id", -1))))    opts = append(opts, findopt.Limit(nPerPage))    cursor, _ := collection.Find(context.Background(), filter, opts...)    var lastValue *bson.Value    var results []bson.Document    for cursor.Next(context.Background()) {        elem := bson.NewDocument()        err := cursor.Decode(elem)        if err != nil {            return results, lastValue, err        }        results = append(results, *elem)        lastValue = elem.Lookup("_id")    }    return results, lastValue, nil}上面调用分页函数的例子:database := client.Database("databaseName")collection := database.Collection("collectionName")startObjectID, _ := objectid.FromHex("5bbafea2b5e14ee3a298fa4a")// Paginate only the latest 20 documents elements, lastID, err := Paginate(collection, startObjectID, 20)for _, e := range elements {    fmt.Println(&e)}// Last seen ObjectID can be used to call next Paginate() fmt.Println("Last seen ObjectID: ", lastID.ObjectID())请注意,您还可以_id用另一个索引字段替换该字段。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go