From aa863a5e10229ab12da45a6f3d4cb1fc82faf139 Mon Sep 17 00:00:00 2001 From: qhd <1766646056@qq.com> Date: Fri, 26 Dec 2025 14:02:25 +0800 Subject: [PATCH] =?UTF-8?q?mongo=E6=95=B0=E6=8D=AE=E5=BA=93=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=EF=BC=9ASaveOrUpdate=20=E6=89=B9=E9=87=8F=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E6=88=96=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mongo/mongo.go | 102 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 97 insertions(+), 5 deletions(-) diff --git a/mongo/mongo.go b/mongo/mongo.go index d02c9ad..e1e1b91 100644 --- a/mongo/mongo.go +++ b/mongo/mongo.go @@ -458,9 +458,13 @@ func Update(ctx context.Context, filter bson.M, update bson.M, collection string if err != nil { return } - filter["tenantId"] = user.TenantId + if !g.IsEmpty(user.TenantId) { + filter["tenantId"] = user.TenantId + } setDoc := update["$set"].(bson.M) - setDoc["updater"] = user.UserName + if !g.IsEmpty(user.UserName) { + setDoc["updater"] = user.UserName + } setDoc["updatedAt"] = gtime.Now().Time update = bson.M{"$set": setDoc} result, err = db.Collection(collection).UpdateMany(ctx, filter, update, opts...) @@ -471,6 +475,88 @@ func Update(ctx context.Context, filter bson.M, update bson.M, collection string return } +// SaveOrUpdate 批量增加或修改 +func SaveOrUpdate(ctx context.Context, filter []bson.M, update []bson.M, collection string, opts ...options.Lister[options.UpdateManyOptions]) (result *mongo.BulkWriteResult, err error) { + if len(filter) == 0 || len(update) == 0 { + err = gerror.New("缺少查询条件或更新数据") + return + } + + if len(filter) != len(update) { + err = gerror.New("查询条件和更新数据的数量必须一致") + return + } + user, err := GetTenantInfo(ctx) + if err != nil { + return + } + + // 构建批量操作模型 + var models []mongo.WriteModel + + for i := 0; i < len(filter); i++ { + // 处理过滤器 + filter[i]["isDeleted"] = false + if !g.IsEmpty(user.TenantId) { + filter[i]["tenantId"] = user.TenantId + } + + // 处理更新数据 + if setDoc, exists := update[i]["$set"].(bson.M); exists { + if !g.IsEmpty(user.UserName) { + setDoc["updater"] = user.UserName + } + setDoc["updatedAt"] = gtime.Now().Time + } else { + // 如果没有$set字段,则创建一个 + setDoc := bson.M{} + if !g.IsEmpty(user.UserName) { + setDoc["updater"] = user.UserName + } + setDoc["updatedAt"] = gtime.Now().Time + update[i]["$set"] = setDoc + } + + // 创建更新操作模型 + updateModel := mongo.NewUpdateOneModel() + updateModel.SetFilter(filter[i]) + updateModel.SetUpdate(update[i]) + updateModel.SetUpsert(true) // 默认不插入新文档 + + // 处理选项参数 + if len(opts) > 0 { + for _, opt := range opts { + var updateOpts options.UpdateManyOptions + optFuncs := opt.List() + for _, fn := range optFuncs { + fn(&updateOpts) + } + if updateOpts.Upsert != nil { + updateModel.SetUpsert(*updateOpts.Upsert) + } + } + } + + models = append(models, updateModel) + } + + // 执行批量操作,无序执行提高性能 + bulkOpts := options.BulkWrite().SetOrdered(false) + bulkResult, err := db.Collection(collection).BulkWrite(ctx, models, bulkOpts) + if err != nil { + return nil, err + } + + // 清理相关缓存 + for _, filterItem := range filter { + err = cleanRedis(ctx, filterItem, user.TenantId, collection) + if err != nil { + glog.Warning(ctx, "清理Redis缓存失败:", err) + } + } + return bulkResult, nil +} + // Insert 插入多条记录 func Insert(ctx context.Context, documents []interface{}, collection string, opts ...options.Lister[options.InsertManyOptions]) (ids []interface{}, err error) { user, err := GetTenantInfo(ctx) @@ -481,11 +567,17 @@ func Insert(ctx context.Context, documents []interface{}, collection string, opt for _, document := range documents { doc := gconv.Map(document) delete(doc, "id") - doc["creator"] = user.UserName + if !g.IsEmpty(user.UserName) { + doc["creator"] = user.UserName + } + if !g.IsEmpty(user.UserName) { + doc["updater"] = user.UserName + } + if !g.IsEmpty(user.TenantId) { + doc["tenantId"] = user.TenantId + } doc["createdAt"] = gtime.Now().Time - doc["updater"] = user.UserName doc["updatedAt"] = gtime.Now().Time - doc["tenantId"] = user.TenantId doc["isDeleted"] = false docs = append(docs, doc) }