我在下面的文章中读到,使用_id的自然排序来执行分页更有效,因为跳过总是从集合的开头开始。
Fast and Efficient Pagination in 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执行上述操作。
发布于 2018-10-08 20:21:47
cursor.skip()方法要求服务器在开始返回结果之前从输入结果集的开头进行扫描。随着偏移量的增加,cursor.skip()将变得更慢。虽然范围查询可以使用索引来避免扫描不需要的文档,但与使用cursor.skip()进行分页相比,随着偏移量的增加,通常会产生更好的性能。有关MongoDB: Pagination Example的详细信息,请参阅
使用当前版本的mongo-go-driver (v0.0.15).An示例进行分页,首先显示最新条目:
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字段。
发布于 2020-10-30 11:22:20
你可以创建一个新的函数,别忘了传递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发布于 2022-02-24 13:51:44
如果不需要分页,则设置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)
...
}https://stackoverflow.com/questions/52677785
复制相似问题