golang实现MongoDB分页查询与聚合管道支持的插件库mongo-go-pagination的使用
Golang实现MongoDB分页查询与聚合管道支持的插件库mongo-go-pagination的使用
安装
$ go get -u -v github.com/gobeam/mongo-go-pagination
或者使用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() {
// 建立MongoDB连接
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")
// 聚合查询示例
// 匹配查询
match := bson.M{"$match": bson.M{"qty": bson.M{"$gt": 10}}}
// 投影查询
projectQuery := bson.M{"$project": bson.M{"_id": 1, "qty": 1}}
// 设置collation(可选)
collation := options.Collation{
Locale: "en",
CaseLevel: true,
}
// 可以链式调用函数并传递多个查询参数
// 这里我们传递了match查询和projection查询作为Aggregate函数的参数
aggPaginatedData, err := New(collection).SetCollation(&collation).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)
}
}
// 打印产品列表
fmt.Printf("Aggregate Product List: %+v\n", aggProductList)
// 打印分页数据
fmt.Printf("Aggregate Pagination Data: %+v\n", aggPaginatedData.Data)
}
普通查询示例
func main() {
// 建立MongoDB连接
ctx, _ := context.WithTimeout(context.Background(), 10*time.Second)
client, err := mongo.Connect(ctx, options.Client().ApplyURI("mongodb://localhost:27017"))
if err != nil {
panic(err)
}
// 普通查询示例
filter := bson.M{}
var limit int64 = 10
var page int64 = 1
collection := client.Database("myaggregate").Collection("stocks")
projection := bson.D{
{"name", 1},
{"qty", 1},
}
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)
}
// paginatedData.Data将为nil,因为数据已通过Decode函数解码
// 分页信息可以在paginatedData.Pagination中访问
// 打印产品列表
fmt.Printf("Normal Find Data: %+v\n", products)
// 打印分页数据
fmt.Printf("Normal find pagination info: %+v\n", paginatedData.Pagination)
}
注意:
paginatedData.data // 对于普通查询,它将是nil,因为数据已通过Decode函数解码
运行测试
$ go test
贡献
欢迎提交Pull Request。对于重大更改,请先提出问题以讨论您希望更改的内容。
请确保适当更新测试。
许可证
MIT License
Copyright (c) 2021
更多关于golang实现MongoDB分页查询与聚合管道支持的插件库mongo-go-pagination的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang实现MongoDB分页查询与聚合管道支持的插件库mongo-go-pagination的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
使用 mongo-go-pagination 实现 MongoDB 分页查询与聚合管道
mongo-go-pagination 是一个专门为 Go 语言 MongoDB 驱动设计的轻量级分页库,它支持基本查询和聚合管道的分页功能。下面我将详细介绍如何使用这个库。
安装
首先安装 mongo-go-pagination 库:
go get github.com/gobeam/mongo-go-pagination
基本查询分页
package main
import (
"context"
"fmt"
"log"
"time"
"github.com/gobeam/mongo-go-pagination"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
type Product struct {
Name string `bson:"name"`
Price float64 `bson:"price"`
CreatedAt time.Time `bson:"created_at"`
}
func main() {
// 连接 MongoDB
client, err := mongo.Connect(context.Background(), options.Client().ApplyURI("mongodb://localhost:27017"))
if err != nil {
log.Fatal(err)
}
defer client.Disconnect(context.Background())
collection := client.Database("testdb").Collection("products")
// 创建一些测试数据
createTestData(collection)
// 基本查询分页
basicPagination(collection)
}
func createTestData(collection *mongo.Collection) {
// 这里可以插入一些测试数据
// ...
}
func basicPagination(collection *mongo.Collection) {
filter := bson.M{"price": bson.M{"$gt": 10}} // 查询条件
// 第1页,每页5条记录
paginatedData, err := pagination.New(collection).Limit(5).Page(1).Filter(filter).Find()
if err != nil {
log.Fatal(err)
}
// 解码结果
var products []Product
for _, raw := range paginatedData.Data {
var product Product
if err := bson.Unmarshal(raw, &product); err != nil {
log.Fatal(err)
}
products = append(products, product)
}
fmt.Printf("Total Records: %d\n", paginatedData.Pagination.Total)
fmt.Printf("Page: %d\n", paginatedData.Pagination.Page)
fmt.Printf("Per Page: %d\n", paginatedData.Pagination.PerPage)
fmt.Printf("Total Pages: %d\n", paginatedData.Pagination.TotalPage)
fmt.Println("Products:")
for _, p := range products {
fmt.Printf("- %s: $%.2f\n", p.Name, p.Price)
}
}
聚合管道分页
func aggregatePagination(collection *mongo.Collection) {
// 定义聚合管道
pipeline := []bson.M{
{
"$match": bson.M{
"price": bson.M{"$gt": 10},
},
},
{
"$group": bson.M{
"_id": "$category",
"count": bson.M{"$sum": 1},
"total": bson.M{"$sum": "$price"},
},
},
{
"$sort": bson.M{"total": -1},
},
}
// 第1页,每页3条记录
paginatedData, err := pagination.New(collection).Limit(3).Page(1).Aggregate(pipeline)
if err != nil {
log.Fatal(err)
}
fmt.Printf("\nAggregation Results (Page %d):\n", paginatedData.Pagination.Page)
for _, raw := range paginatedData.Data {
var result struct {
ID string `bson:"_id"`
Count int `bson:"count"`
Total float64 `bson:"total"`
}
if err := bson.Unmarshal(raw, &result); err != nil {
log.Fatal(err)
}
fmt.Printf("- Category: %s, Count: %d, Total: $%.2f\n", result.ID, result.Count, result.Total)
}
}
高级功能
1. 排序
// 添加排序条件
paginatedData, err := pagination.New(collection).
Limit(5).
Page(1).
Sort("price", -1). // -1 表示降序
Filter(filter).
Find()
2. 选择字段
// 只选择特定字段
paginatedData, err := pagination.New(collection).
Limit(5).
Page(1).
Select(bson.M{"name": 1, "price": 1}).
Filter(filter).
Find()
3. 自定义解码
// 自定义解码方式
var products []Product
paginatedData, err := pagination.New(collection).
Limit(5).
Page(1).
Filter(filter).
Decode(&products)
性能考虑
- 对于大型集合,确保查询字段有适当的索引
- 避免在分页查询中使用
$where
或 JavaScript 表达式 - 考虑使用
hint()
强制使用特定索引
总结
mongo-go-pagination 提供了简单易用的 API 来实现 MongoDB 分页功能,主要特点包括:
- 支持基本查询和聚合管道的分页
- 提供丰富的分页元数据(总记录数、总页数等)
- 灵活的排序和字段选择
- 与官方 MongoDB Go 驱动无缝集成
对于大多数分页需求,这个库都能提供简洁高效的解决方案。