首頁 > 後端開發 > Golang > 在 Go 中解組 MongoDB 文件時如何忽略空值?

在 Go 中解組 MongoDB 文件時如何忽略空值?

Susan Sarandon
發布: 2025-01-02 16:23:07
原創
881 人瀏覽過

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

在MongoDB 文件解組期間忽略空值

將MongoDB 文件解組到包含不可為空字串欄位的Go 結構時字串,遇到null文檔中的值可能會導致錯誤。為了解決這個問題,有必要找到一種方法在解組過程中忽略這些空值。

使用自訂解碼器

處理空值的一種方法是為字串類型建立自訂解碼器。此自訂解碼器將識別空值並透過將對應欄位設為空字串來處理它們,從而有效地忽略空值:

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

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
    var err error
    switch vr.Type() {
    case bsontype.String:
        if str, err = vr.ReadString(); err != nil {
            return err
        }
    case bsontype.Null:
        if err = vr.ReadNull(); err != nil {
            return err
        }
    default:
        return fmt.Errorf("cannot decode %v into a string type", vr.Type())
    }

    val.SetString(str)
    return nil
}
登入後複製

然後可以使用bsoncodec.Registry 註冊此自訂解碼器並應用於一個mongo.Client 物件:

clientOpts := options.Client().
    ApplyURI("mongodb://localhost:27017/").
    SetRegistry(
        bson.NewRegistryBuilder().
            RegisterDecoder(reflect.TypeOf(""), nullawareStrDecoder{}).
            Build(),
    )
client, err := mongo.Connect(ctx, clientOpts)
登入後複製

建立類型中立的Null-Aware解碼器

要處理多種類型的空值,可以建立一個類型中立的解碼器來檢查空值,如果遇到空值,則將對應欄位設為零數值類型:

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")
    }
    if err := vr.ReadNull(); err != nil {
        return err
    }

    val.Set(d.zeroValue)
    return nil
}
登入後複製

此解碼器可以使用bsoncodec 註冊。特定類型或所有類型的登錄:

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

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)})
}
登入後複製

以上是在 Go 中解組 MongoDB 文件時如何忽略空值?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板