-
Notifications
You must be signed in to change notification settings - Fork 36
Home
Roshan Ranabhat edited this page Apr 26, 2021
·
3 revisions
This package is helper library to implement Mongodb Pagination using Golang for official mongodb/mongo-go-driver package which supports both normal queries and Aggregation pipelines with all information like Total records, Page, Per Page, Previous , Next, Total Page and query results.
Code is available in the Example folder.
$ go get -u -v github.com/gobeam/mongo-go-pagination
or with dep
$ dep ensure -add github.com/gobeam/mongo-go-pagination
package main
import (
"context"
"fmt"
. "github.com/gobeam/mongo-go-pagination"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"time"
)
type Product struct {
Id primitive.ObjectID `json:"_id" bson:"_id"`
Name string `json:"name" bson:"name"`
Quantity float64 `json:"qty" bson:"qty"`
Price float64 `json:"price" bson:"price"`
}
func main() {
// Establishing mongo db connection
ctx, _ := context.WithTimeout(context.Background(), 10*time.Second)
client, err := mongo.Connect(ctx, options.Client().ApplyURI("mongodb://localhost:27017"))
if err != nil {
panic(err)
}
var limit int64 = 10
var page int64 = 1
collection := client.Database("myaggregate").Collection("stocks")
//Example for Aggregation
//match query
match := bson.M{"$match": bson.M{"qty": bson.M{"$gt": 10}}}
//group query
projectQuery := bson.M{"$project": bson.M{"_id": 1, "qty": 1}}
// you can easily chain function and pass multiple query like here we are passing match
// query and projection query as params in Aggregate function you cannot use filter with Aggregate
// because you can pass filters directly through Aggregate param
aggPaginatedData, err := New(collection).Context(ctx).Limit(limit).Page(page).Sort("price", -1).Aggregate(match, projectQuery)
if err != nil {
panic(err)
}
var aggProductList []Product
for _, raw := range aggPaginatedData.Data {
var product *Product
if marshallErr := bson.Unmarshal(raw, &product); marshallErr == nil {
aggProductList = append(aggProductList, *product)
}
}
// print ProductList
fmt.Printf("Aggregate Product List: %+v\n", aggProductList)
// print pagination data
fmt.Printf("Aggregate Pagination Data: %+v\n", aggPaginatedData.Data)
}
func main() {
// Establishing mongo db connection
ctx, _ := context.WithTimeout(context.Background(), 10*time.Second)
client, err := mongo.Connect(ctx, options.Client().ApplyURI("mongodb://localhost:27017"))
if err != nil {
panic(err)
}
// Example for Normal Find query
filter := bson.M{}
var limit int64 = 10
var page int64 = 1
collection := client.Database("myaggregate").Collection("stocks")
projection := bson.D{
{"name", 1},
{"qty", 1},
}
// Querying paginated data
// Sort and select are optional
// Multiple Sort chaining is also allowed
// If you want to do some complex sort like sort by score(weight) for full text search fields you can do it easily
// sortValue := bson.M{
// "$meta" : "textScore",
// }
// aggPaginatedData, err := paginate.New(collection).Context(ctx).Limit(limit).Page(page).Sort("score", sortValue)...
var products []Product
paginatedData, err := New(collection).Context(ctx).Limit(limit).Page(page).Sort("price", -1).Select(projection).Filter(filter).Decode(&products).Find()
if err != nil {
panic(err)
}
// paginated data or paginatedData.Data will be nil because data is already decoded on through Decode function
// pagination info can be accessed in paginatedData.Pagination
// print ProductList
fmt.Printf("Normal Find Data: %+v\n", products)
// print pagination data
fmt.Printf("Normal find pagination info: %+v\n", paginatedData.Pagination)
}
$ go test