Das Ignorieren von Nullwerten während des Unmarshalling-Prozesses von MongoDB-Dokumenten in Go-Strukturen ist eine häufige Notwendigkeit. In diesem Artikel untersuchen wir eine Lösung mit benutzerdefinierten Decodern im Mongo-Go-Treiber.
Zunächst behandeln wir Nullwerte für Strings. Wir definieren einen benutzerdefinierten Decoder, der Nullwerte als leere Zeichenfolgen interpretiert:
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 }
Um diesen benutzerdefinierten Decoder für einen bestimmten Client zu verwenden, registrieren wir ihn in der Registrierung des Clients:
clientOpts := options.Client(). ApplyURI("mongodb://localhost:27017/"). SetRegistry( bson.NewRegistryBuilder(). RegisterDecoder(reflect.TypeOf(""), nullawareStrDecoder{}). Build(), ) client, err := mongo.Connect(ctx, clientOpts)
Ein umfassenderer Ansatz besteht darin, einen typneutralen Decoder zu erstellen Decoder, der Nullwerte für jeden Typ verarbeitet:
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 }
Für jeden Typ, für den Nullwerte ignoriert werden sollen, können wir diesen Decoder verwenden. Zum Beispiel für Zeichenfolgen und Ganzzahlen:
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)
Mit diesem Setup werden Werte für die angegebenen Typen auf ihre jeweiligen Nullwerte gesetzt, wenn beim Unmarshalling Nullen angetroffen werden.
Das obige ist der detaillierte Inhalt vonWie gehe ich beim Unmarshalling von MongoDB-Dokumenten in Go mit Nullwerten um?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!