Ignorieren von Nullwerten beim Unmarshalling von MongoDB-Dokumenten
Beim Unmarshalling eines MongoDB-Dokuments in eine Go-Struktur, die nicht nullbare Zeichenfolgenfelder enthält, tritt Null auf Werte im Dokument können zu Fehlern führen. Um dieses Problem zu beheben, muss eine Möglichkeit gefunden werden, diese Nullwerte beim Unmarshalling zu ignorieren.
Verwendung eines benutzerdefinierten Decoders
Ein Ansatz zum Umgang mit Nullwerten ist Erstellen eines benutzerdefinierten Decoders für den String-Typ. Dieser benutzerdefinierte Decoder erkennt Nullwerte und verarbeitet sie, indem er das entsprechende Feld auf eine leere Zeichenfolge setzt und den Nullwert effektiv ignoriert:
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 }
Dieser benutzerdefinierte Decoder kann dann bei einer bsoncodec.Registry registriert und angewendet werden ein mongo.Client-Objekt:
clientOpts := options.Client(). ApplyURI("mongodb://localhost:27017/"). SetRegistry( bson.NewRegistryBuilder(). RegisterDecoder(reflect.TypeOf(""), nullawareStrDecoder{}). Build(), ) client, err := mongo.Connect(ctx, clientOpts)
Erstellen eines typneutralen Null-Aware Decoder
Um Nullwerte für mehrere Typen zu verarbeiten, ist es möglich, einen einzelnen, typneutralen Decoder zu erstellen, der nach Nullwerten sucht und, wenn er gefunden wird, das entsprechende Feld auf den Nullwert seiner Werte setzt Typ:
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 }
Dieser Decoder kann bei einer bsoncodec.Registry für bestimmte Typen oder für alle Typen registriert werden:
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)}) }
Das obige ist der detaillierte Inhalt vonWie ignoriere ich Nullwerte beim Unmarshalling von MongoDB-Dokumenten in Go?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!