首页 > 后端开发 > Golang > 在 Go 中解组 MongoDB 文档时如何处理空值?

在 Go 中解组 MongoDB 文档时如何处理空值?

Susan Sarandon
发布: 2024-12-30 07:20:10
原创
743 人浏览过

How to Handle Null Values When Unmarshalling MongoDB Documents in Go?

在解组 MongoDB 文档时处理空值

在将 MongoDB 文档解组到 Go 结构的过程中忽略空值是一种常见的需求。在本文中,我们将探索在 mongo-go-driver 中使用自定义解码器的解决方案。

自定义字符串解码器

首先,让我们处理字符串的空值。我们定义一个将 null 值解释为空字符串的自定义解码器:

import (
    "go.mongodb.org/mongo-driver/bson/bsoncodec"
    "go.mongodb.org/mongo-driver/bson/bsonrw"
)

type nullawareStrDecoder struct{}

func (nullawareStrDecoder) DecodeValue(dctx bsoncodec.DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
    if !val.CanSet() || val.Kind() != reflect.String {
        return errors.New("bad type or not settable")
    }
    var str string
    switch vr.Type() {
    case bsontype.String:
        str, _ = vr.ReadString()
    case bsontype.Null:
        _ = vr.ReadNull()
    default:
        return fmt.Errorf("cannot decode %v into a string type", vr.Type())
    }

    val.SetString(str)
    return nil
}
登录后复制

利用自定义解码器

要为特定客户端使用此自定义解码器,我们将其注册到客户端的注册表:

clientOpts := options.Client().
    ApplyURI("mongodb://localhost:27017/").
    SetRegistry(
        bson.NewRegistryBuilder().
            RegisterDecoder(reflect.TypeOf(""), nullawareStrDecoder{}).
            Build(),
    )
client, err := mongo.Connect(ctx, clientOpts)
登录后复制

任何空值的类型中立解码器

更全面的方法涉及创建一个处理任何类型的 null 值的类型中性解码器:

import (
    "go.mongodb.org/mongo-driver/bson/bsoncodec"
    "go.mongodb.org/mongo-driver/bson/bsonrw"
    "reflect"
)

type nullawareDecoder struct {
    defDecoder bsoncodec.ValueDecoder
    zeroValue  reflect.Value
}

func (d *nullawareDecoder) DecodeValue(dctx bsoncodec.DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
    if vr.Type() != bsontype.Null {
        return d.defDecoder.DecodeValue(dctx, vr, val)
    }

    if !val.CanSet() {
        return errors.New("value not settable")
    }
    _ = vr.ReadNull()
    val.Set(d.zeroValue)
    return nil
}
登录后复制

对于我们希望忽略 null 的每种类型,我们可以使用此解码器。例如,对于字符串和整数:

customValues := []interface{}{
    "",       // string
    int(0),   // int
}

rb := bson.NewRegistryBuilder()
for _, v := range customValues {
    t := reflect.TypeOf(v)
    defDecoder, err := bson.DefaultRegistry.LookupDecoder(t)
    if err != nil {
        panic(err)
    }
    rb.RegisterDecoder(t, &nullawareDecoder{defDecoder, reflect.Zero(t)})
}

clientOpts := options.Client().
    ApplyURI("mongodb://localhost:27017/").
    SetRegistry(rb.Build())
client, err := mongo.Connect(ctx, clientOpts)
登录后复制

使用此设置,当解组过程中遇到空值时,指定类型的值将设置为其各自的零值。

以上是在 Go 中解组 MongoDB 文档时如何处理空值?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板