isEmptyWithZero 判断是否为空值,但保留 int 类型的 0 值
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
@@ -471,6 +472,7 @@ func (m *MongoDB) Update(ctx context.Context, filter bson.M, update bson.M, coll
|
|||||||
|
|
||||||
// RandomSoftDelete 随机软删除个文档的 _id
|
// RandomSoftDelete 随机软删除个文档的 _id
|
||||||
func (m *MongoDB) RandomSoftDelete(ctx context.Context, limit int, collection string, opts ...options.Lister[options.UpdateManyOptions]) (result *mongo.UpdateResult, err error) {
|
func (m *MongoDB) RandomSoftDelete(ctx context.Context, limit int, collection string, opts ...options.Lister[options.UpdateManyOptions]) (result *mongo.UpdateResult, err error) {
|
||||||
|
_ = opts
|
||||||
// 步骤 1: 使用聚合管道的 $sample 操作符随机抽取5个文档的 _id
|
// 步骤 1: 使用聚合管道的 $sample 操作符随机抽取5个文档的 _id
|
||||||
pipeline := mongo.Pipeline{
|
pipeline := mongo.Pipeline{
|
||||||
// 阶段1: 为每个文档添加一个 0-1 之间的随机数字段 'random'
|
// 阶段1: 为每个文档添加一个 0-1 之间的随机数字段 'random'
|
||||||
@@ -665,7 +667,11 @@ func EntityToBson(entity interface{}) (bson.M, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// EntityToBsonWithFilter 将 *entity/entity 转换为 bson.M,并可选择是否过滤空值
|
// EntityToBsonWithFilter 将 *entity/entity 转换为 bson.M,并可选择是否过滤空值
|
||||||
// filterEmpty: 为 true 时会过滤掉空值字段(nil、空字符串、空切片、空map等)
|
// filterEmpty: 为 true 时会过滤掉空值字段(nil、空字符串、空切片、空map等),但保留 int 类型的 0 值
|
||||||
|
// 支持:
|
||||||
|
// - 未传值的指针(如 *consts.AssetStatus(nil))会被过滤
|
||||||
|
// - 传值为0的指针(如 *consts.AssetStatus(0))不会被过滤
|
||||||
|
// - 非0的整数值不会被过滤
|
||||||
func EntityToBsonWithFilter(entity interface{}, filterEmpty bool) (bson.M, error) {
|
func EntityToBsonWithFilter(entity interface{}, filterEmpty bool) (bson.M, error) {
|
||||||
// 第一步:判断入参是否为 nil 或无效类型
|
// 第一步:判断入参是否为 nil 或无效类型
|
||||||
if entity == nil {
|
if entity == nil {
|
||||||
@@ -686,10 +692,43 @@ func EntityToBsonWithFilter(entity interface{}, filterEmpty bool) (bson.M, error
|
|||||||
// 如果需要过滤空值
|
// 如果需要过滤空值
|
||||||
if filterEmpty {
|
if filterEmpty {
|
||||||
for key, value := range bsonMap {
|
for key, value := range bsonMap {
|
||||||
if g.IsEmpty(value) {
|
// 判断是否为空值,但保留 int 类型的 0 值
|
||||||
|
if isEmptyWithZero(value) {
|
||||||
delete(bsonMap, key)
|
delete(bsonMap, key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return bsonMap, nil
|
return bsonMap, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// isEmptyWithZero 判断是否为空值,但保留 int 类型的 0 值
|
||||||
|
// 支持区分"未传值"和"传值为0"的情况:
|
||||||
|
// - *int(nil) 或 *consts.AssetStatus(nil) → 返回 true(过滤掉)
|
||||||
|
// - *int(0) 或 *consts.AssetStatus(0) → 返回 false(保留)
|
||||||
|
// - int(0) 或 consts.AssetStatus(0) → 返回 false(保留)
|
||||||
|
func isEmptyWithZero(value interface{}) bool {
|
||||||
|
// 先检查 value 是否为 nil
|
||||||
|
if value == nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
rv := reflect.ValueOf(value)
|
||||||
|
kind := rv.Kind()
|
||||||
|
// 处理 nil 指针
|
||||||
|
if kind == reflect.Ptr {
|
||||||
|
if rv.IsNil() {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
// 判断时如果是指针,需要获取指向的值的类型
|
||||||
|
kind = rv.Elem().Kind()
|
||||||
|
}
|
||||||
|
// 数字类型(int/uint/float)都保留,包括 0 值
|
||||||
|
switch kind {
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
|
||||||
|
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
|
||||||
|
reflect.Float32, reflect.Float64:
|
||||||
|
return false
|
||||||
|
default:
|
||||||
|
// 其他类型使用 g.IsEmpty 判断
|
||||||
|
return g.IsEmpty(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user