优化mongo,封装count逻辑,处理objectId

This commit is contained in:
2026-01-07 16:19:28 +08:00
parent 40c5d5de79
commit a1f9e627e4
3 changed files with 47 additions and 52 deletions

View File

@@ -27,16 +27,16 @@ type OrderBy struct {
Order OrderEnum `p:"order"` //排序方式 Order OrderEnum `p:"order"` //排序方式
} }
type MongoBaseDO struct { type MongoBaseDO struct {
Id bson.ObjectID `bson:"_id,omitempty" json:"id"` // MongoDB 默认 ID Id *bson.ObjectID `bson:"_id,omitempty" json:"id"` // MongoDB 默认 ID
Creator interface{} `bson:"creator,omitempty" json:"creator"` Creator interface{} `bson:"creator,omitempty" json:"creator"`
CreatedAt time.Time `bson:"created_at,omitempty" json:"createdAt"` CreatedAt *time.Time `bson:"createdAt,omitempty" json:"createdAt"`
Updater interface{} `bson:"updater,omitempty" json:"updater"` Updater interface{} `bson:"updater,omitempty" json:"updater"`
UpdatedAt time.Time `bson:"updated_at,omitempty" json:"updatedAt"` UpdatedAt *time.Time `bson:"updatedAt,omitempty" json:"updatedAt"`
TenantId interface{} `bson:"tenant_id" json:"tenantId" default:"1"` // 租户ID TenantId interface{} `bson:"tenantId" json:"tenantId" default:"1"` // 租户ID
IsDeleted bool `bson:"is_deleted" json:"isDeleted" default:"false"` IsDeleted bool `bson:"isDeleted" json:"isDeleted" default:"false"`
} }
type User struct { type User struct {
UserName interface{} `bson:"user_name" json:"userName"` // MongoDB 默认 ID UserName interface{} `bson:"userName" json:"userName"` // MongoDB 默认 ID
TenantId interface{} `bson:"tenant_id" json:"tenantId"` // 租户ID TenantId interface{} `bson:"tenantId" json:"tenantId"` // 租户ID
} }

View File

@@ -86,7 +86,7 @@ func (d *log) List(ctx context.Context, filter *dto.ListLogsReq, sortFields ...s
} }
var logs []*entity.OperationLog var logs []*entity.OperationLog
err = mongo.DB().Find(ctx, bsonFilter, &logs, consts.OperationLogCollection, nil, nil) _, err = mongo.DB().Find(ctx, bsonFilter, &logs, consts.OperationLogCollection, nil, nil)
if err != nil { if err != nil {
return nil, 0, err return nil, 0, err
} }

View File

@@ -4,7 +4,6 @@ import (
"context" "context"
"errors" "errors"
"fmt" "fmt"
"reflect"
"strings" "strings"
"sync" "sync"
"time" "time"
@@ -12,6 +11,7 @@ import (
"gitee.com/red-future---jilin-g/common/beans" "gitee.com/red-future---jilin-g/common/beans"
"gitee.com/red-future---jilin-g/common/log/model/dto" "gitee.com/red-future---jilin-g/common/log/model/dto"
"github.com/gogf/gf/v2/container/gvar" "github.com/gogf/gf/v2/container/gvar"
"github.com/gogf/gf/v2/os/grpool"
"gitee.com/red-future---jilin-g/common/redis" "gitee.com/red-future---jilin-g/common/redis"
"gitee.com/red-future---jilin-g/common/utils" "gitee.com/red-future---jilin-g/common/utils"
@@ -174,8 +174,11 @@ func reconnect() error {
return gerror.New("MongoDB重连失败已达到最大重试次数") return gerror.New("MongoDB重连失败已达到最大重试次数")
} }
var logPool *grpool.Pool
// init 初始化MongoDB连接 // init 初始化MongoDB连接
func init() { func init() {
logPool = grpool.New(10)
// 按需初始化:没有配置 mongo.address 则跳过 // 按需初始化:没有配置 mongo.address 则跳过
mongoAddr = g.Cfg().MustGet(context.Background(), "mongo.address").String() mongoAddr = g.Cfg().MustGet(context.Background(), "mongo.address").String()
if mongoAddr == "" { if mongoAddr == "" {
@@ -225,10 +228,10 @@ func close() {
const PageSize = 20 const PageSize = 20
// Find 查询多条记录 // Find 查询多条记录
func (m *MongoDB) Find(ctx context.Context, filter bson.M, result interface{}, collection string, page *beans.Page, orderBy []beans.OrderBy) (err error) { func (m *MongoDB) Find(ctx context.Context, filter bson.M, result interface{}, collection string, page *beans.Page, orderBy []beans.OrderBy) (total int64, err error) {
if err = utils.ValidStructPtr(result); err != nil { //if err = utils.ValidStructPtr(result); err != nil {
return // return
} //}
user, err := utils.GetUserInfo(ctx) user, err := utils.GetUserInfo(ctx)
if err != nil { if err != nil {
return return
@@ -237,12 +240,6 @@ func (m *MongoDB) Find(ctx context.Context, filter bson.M, result interface{}, c
filterKey := fmt.Sprintf("%+v", filter) filterKey := fmt.Sprintf("%+v", filter)
optionsKey := fmt.Sprintf("%+v%+v", page, orderBy) optionsKey := fmt.Sprintf("%+v%+v", page, orderBy)
redisKey := fmt.Sprintf(redis.List, user.TenantId, collection, filterKey, optionsKey) redisKey := fmt.Sprintf(redis.List, user.TenantId, collection, filterKey, optionsKey)
resultValue := reflect.ValueOf(result)
if resultValue.IsNil() || resultValue.IsZero() {
return errors.New("result不能为空")
}
resultValue = resultValue.Elem()
listField := resultValue.FieldByName("List")
if m.Cache { if m.Cache {
var resultStr *gvar.Var var resultStr *gvar.Var
resultStr, err = redis.RedisClient.Get(ctx, redisKey) resultStr, err = redis.RedisClient.Get(ctx, redisKey)
@@ -250,7 +247,10 @@ func (m *MongoDB) Find(ctx context.Context, filter bson.M, result interface{}, c
return return
} }
if !resultStr.IsEmpty() { if !resultStr.IsEmpty() {
resultStr.Structs(listField.Addr().Interface()) if err = resultStr.Structs(result); err != nil {
return
}
total = int64(len(resultStr.Array()))
return return
} }
} }
@@ -261,19 +261,20 @@ func (m *MongoDB) Find(ctx context.Context, filter bson.M, result interface{}, c
skip := int64(0) skip := int64(0)
if page != nil { if page != nil {
limit = page.PageSize limit = page.PageSize
skip = (page.PageNum - 1) * limit if limit == -1 {
if skip <= 0 {
skip = 0 skip = 0
} else {
skip = (page.PageNum - 1) * limit
} }
} }
total, err := m.Count(ctx, filter, collection)
if err != nil || total == 0 {
return
}
utils.SetValue(ctx, result, "Total", total)
opt := options.Find().SetSkip(skip) opt := options.Find().SetSkip(skip)
if limit != -1 { if limit != -1 {
opt.SetLimit(limit) opt.SetLimit(limit)
} else {
total, err = m.Count(ctx, filter, collection)
if err != nil || total == 0 {
return
}
} }
if orderBy == nil { if orderBy == nil {
opt.SetSort(bson.M{"createdAt": -1}) opt.SetSort(bson.M{"createdAt": -1})
@@ -293,25 +294,17 @@ func (m *MongoDB) Find(ctx context.Context, filter bson.M, result interface{}, c
if err != nil { if err != nil {
return return
} }
if limit == -1 {
total = int64(cur.RemainingBatchLength())
}
defer cur.Close(ctx) defer cur.Close(ctx)
if err = cur.All(ctx, result); err != nil {
// 先解码到[]bson.M再转换到目标类型处理datetime到string的转换
var docs []bson.M
if err = cur.All(ctx, &docs); err != nil {
return
}
for _, v := range docs {
v["id"] = v["_id"].(bson.ObjectID).Hex()
delete(v, "_id")
}
// 使用gconv转换处理类型转换
if err = gconv.Structs(docs, listField.Addr().Interface()); err != nil {
return return
} }
if m.Cache { if m.Cache {
err = redis.RedisClient.SetEX(ctx, redisKey, docs, int64(time.Hour)) err = redis.RedisClient.SetEX(ctx, redisKey, result, int64(time.Hour))
if err != nil { if err != nil {
return err return
} }
} }
return return
@@ -408,16 +401,17 @@ func (m *MongoDB) Delete(ctx context.Context, filter bson.M, collection string,
return return
} }
filter["tenantId"] = user.TenantId filter["tenantId"] = user.TenantId
var rows []interface{}
if err = m.Find(ctx, filter, &rows, collection, nil, nil); err != nil {
return
}
r, err := db.Collection(collection).DeleteMany(ctx, filter, opts...) r, err := db.Collection(collection).DeleteMany(ctx, filter, opts...)
if err != nil { if err != nil {
return return
} }
count = r.DeletedCount count = r.DeletedCount
err = m.CleanRedis(ctx, filter, user.TenantId, collection) err = m.CleanRedis(ctx, filter, user.TenantId, collection)
//写日志
var rows []interface{}
if _, err = m.Find(ctx, filter, &rows, collection, nil, nil); err != nil {
return
}
serverName := g.Cfg().MustGet(ctx, "server.name").String() serverName := g.Cfg().MustGet(ctx, "server.name").String()
logRedisKey := fmt.Sprintf("log:%s", serverName) logRedisKey := fmt.Sprintf("log:%s", serverName)
if _, err = redis.AddToStream(ctx, logRedisKey, &dto.RecordCreateLogReq{ if _, err = redis.AddToStream(ctx, logRedisKey, &dto.RecordCreateLogReq{
@@ -450,17 +444,18 @@ func (m *MongoDB) Update(ctx context.Context, filter bson.M, update bson.M, coll
} }
setDoc["updatedAt"] = gtime.Now().Time setDoc["updatedAt"] = gtime.Now().Time
update = bson.M{"$set": setDoc} update = bson.M{"$set": setDoc}
var rows []interface{}
if err = m.Find(ctx, filter, &rows, collection, nil, nil); err != nil {
return
}
result, err = db.Collection(collection).UpdateMany(ctx, filter, update, opts...) result, err = db.Collection(collection).UpdateMany(ctx, filter, update, opts...)
if err != nil { if err != nil {
return return
} }
err = m.CleanRedis(ctx, filter, user.TenantId, collection) err = m.CleanRedis(ctx, filter, user.TenantId, collection)
//写日志
serverName := g.Cfg().MustGet(ctx, "server.name").String() serverName := g.Cfg().MustGet(ctx, "server.name").String()
logRedisKey := fmt.Sprintf("log:%s", serverName) logRedisKey := fmt.Sprintf("log:%s", serverName)
var rows []interface{}
if _, err = m.Find(ctx, filter, &rows, collection, nil, nil); err != nil {
return
}
if _, err = redis.AddToStream(ctx, logRedisKey, &dto.RecordCreateLogReq{ if _, err = redis.AddToStream(ctx, logRedisKey, &dto.RecordCreateLogReq{
ServiceName: serverName, ServiceName: serverName,
Collection: collection, Collection: collection,
@@ -636,7 +631,7 @@ func (m *MongoDB) Insert(ctx context.Context, documents []interface{}, collectio
rows = append(rows, doc) rows = append(rows, doc)
} else { } else {
filter := bson.M{"_id": bson.M{"$in": ids}} filter := bson.M{"_id": bson.M{"$in": ids}}
if err = m.Find(ctx, filter, &rows, collection, nil, nil); err != nil { if _, err = m.Find(ctx, filter, &rows, collection, nil, nil); err != nil {
return return
} }
} }