187 lines
3.7 KiB
Go
187 lines
3.7 KiB
Go
package mongo
|
|
|
|
import (
|
|
// "log"
|
|
"context"
|
|
// "fmt"
|
|
// "encoding/base64"
|
|
|
|
// "go.mongodb.org/mongo-driver/v2/mongo/options"
|
|
"go.mongodb.org/mongo-driver/v2/bson"
|
|
|
|
// "git.gsuntres.com/boxtep/boxtep/core"
|
|
)
|
|
|
|
// Find is used to fetch the first page of data.
|
|
func (c *MongoClient) Find(ctx context.Context, database, name string, filter bson.M, limit int64) (bson.M, error) {
|
|
|
|
// 1. Prepare to query.
|
|
collection := c.GetCollection(database, name)
|
|
|
|
pageSize := max(limit, c.Limit)
|
|
|
|
|
|
// id := DecodeCursor(nextCursor)
|
|
|
|
// filter["_id"] = bson.M{"_id": bson.M{"$gt": id}}
|
|
// opts := options.Find().
|
|
// SetLimit(pageSize + 1).
|
|
// SetSort(bson.M{"_id": 1})
|
|
// id := DecodeCursor(nextCursor)
|
|
sort := bson.M{"_id": 1}
|
|
// filter["_id"] = bson.M{"_id": bson.M{"$gt": id}}
|
|
|
|
pipeline := BuildPaginationPipeline(0, pageSize + 1, filter, sort)
|
|
|
|
// 2. Query
|
|
cursor, err := collection.Aggregate(ctx, pipeline)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer cursor.Close(ctx)
|
|
|
|
// 3. Build results
|
|
var facetResults []bson.M
|
|
if err = cursor.All(ctx, &facetResults); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
root := facetResults[0]
|
|
|
|
data := root["data"].(bson.A)
|
|
|
|
metadata := root["metadata"].(bson.A)
|
|
|
|
var totalValue any
|
|
if len(metadata) != 0 {
|
|
metadataRoot := metadata[0].(bson.M)
|
|
totalValue = metadataRoot["total"]
|
|
}
|
|
|
|
var total int64
|
|
switch v := totalValue.(type) {
|
|
case int32:
|
|
total = int64(v)
|
|
case int64:
|
|
total = v
|
|
default:
|
|
total = 0
|
|
}
|
|
|
|
hasMore := false
|
|
if int64(len(data)) > pageSize {
|
|
hasMore = true
|
|
data = data[:pageSize]
|
|
}
|
|
|
|
out := bson.M{
|
|
"data": data,
|
|
"has_more": hasMore,
|
|
"total": total,
|
|
}
|
|
|
|
if hasMore {
|
|
// next cursor
|
|
var last bson.M = data[len(data) - 1].(bson.M)
|
|
var nextCursor string
|
|
lastId := last["_id"]
|
|
|
|
nextCursor = EncodeCursor(lastId.(bson.ObjectID))
|
|
|
|
out["next_cursor"] = nextCursor
|
|
}
|
|
|
|
// _data, err := bson.Marshal(out)
|
|
// if err != nil {
|
|
// return nil, err
|
|
// }
|
|
|
|
// var r bson.M
|
|
// if err := bson.Unmarshal(_data, &r); err != nil {
|
|
// return nil, err
|
|
// }
|
|
|
|
return out, nil
|
|
}
|
|
|
|
func (c *MongoClient) FindOffset(ctx context.Context, database, name string, filter bson.M, offset, limit int64) (bson.M, error) {
|
|
// 1. Prepare to query.
|
|
collection := c.GetCollection(database, name)
|
|
|
|
finalLimit := max(limit, c.Limit)
|
|
|
|
pipeline := BuildPaginationPipeline(offset, finalLimit, filter, nil)
|
|
|
|
// 2. Query
|
|
cursor, err := collection.Aggregate(ctx, pipeline)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer cursor.Close(ctx)
|
|
|
|
// 3. Build results
|
|
var facetResults []bson.M
|
|
if err = cursor.All(ctx, &facetResults); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
root := facetResults[0]
|
|
|
|
data := root["data"].(bson.A)
|
|
|
|
metadata := root["metadata"].(bson.A)
|
|
|
|
var totalValue any
|
|
if len(metadata) != 0 {
|
|
metadataRoot := metadata[0].(bson.M)
|
|
totalValue = metadataRoot["total"]
|
|
}
|
|
|
|
var total int64
|
|
switch v := totalValue.(type) {
|
|
case int32:
|
|
total = int64(v)
|
|
case int64:
|
|
total = v
|
|
default:
|
|
total = 0
|
|
}
|
|
|
|
hasMore := false
|
|
if int64(len(data)) > finalLimit {
|
|
hasMore = true
|
|
data = data[:finalLimit]
|
|
}
|
|
|
|
out := bson.M{
|
|
"data": data,
|
|
"offset": offset,
|
|
"limit": finalLimit,
|
|
"has_more": hasMore,
|
|
"total": total,
|
|
}
|
|
|
|
return out, nil
|
|
}
|
|
// func (c *MongoClient) FindNext(ctx context.Context, database, name string, filter bson.M, nextCursor string, limit int64) ([]bson.M, error) {
|
|
// collection := c.GetCollection(database, name)
|
|
|
|
// opts := options.Find().
|
|
// SetLimit(max(limit, c.Limit)).
|
|
// SetSort()
|
|
|
|
// cursor, err := collection.Find(ctx, filter)
|
|
// if err != nil {
|
|
// return nil, err
|
|
// }
|
|
|
|
// var results []bson.M
|
|
// if err = cursor.All(ctx, &results); err != nil {
|
|
// return nil, err
|
|
// }
|
|
|
|
// return results, err
|
|
// }
|
|
|
|
// func EncodeCursor()
|