Open shanweie opened 11 months ago
Mongo Options 的原始碼在這裡:https://github.com/zeromicro/go-zero/blob/master/core/stores/mon/options.go
import (
"reflect"
"go.mongodb.org/mongo-driver/bson"
// 引入 go mongo-driver
mopt "go.mongodb.org/mongo-driver/mongo/options"
"github.com/zeromicro/go-zero/core/stores/mon"
)
registry := bson.NewRegistry()
registry.RegisterTypeEncoder(reflect.TypeOf(decimal.Decimal{}), &mongo.MongoDecimal{})
// 使用 SetRegistry 註冊
opts := mon.Option(mopt.SetRegistry(registry)) // opts 的 type 會是 Option,這是 go-zero 自己訂的 type
conn := mon.MustNewModel(url, db, collection, opts)
資料來源:
Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑🤝🧑👫🧑🏿🤝🧑🏻👩🏾🤝👨🏿👬🏿
The source code of Mongo Options is here: https://github.com/zeromicro/go-zero/blob/master/core/stores/mon/options.go
import (
"reflect"
"go.mongodb.org/mongo-driver/bson"
//Introduce go mongo-driver
mopt "go.mongodb.org/mongo-driver/mongo/options"
"github.com/zeromicro/go-zero/core/stores/mon"
)
registry := bson.NewRegistry()
registry.RegisterTypeEncoder(reflect.TypeOf(decimal.Decimal{}), &mongo.MongoDecimal{})
//Register using SetRegistry
opts := mon.Option(mopt.SetRegistry(registry)) // The type of opts will be Option, which is the type set by go-zero itself
conn := mon.MustNewModel(url, db, collection, opts)
source:
mongo-driver v1.12.1,里面没有这个mopt.SetRegistry(registry)这个方法
Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑🤝🧑👫🧑🏿🤝🧑🏻👩🏾🤝👨🏿👬🏿
mongo-driver v1.12.1, there is no mopt.SetRegistry(registry) method in it
@kevwan Hey! I have a problem with transfering mongo decimal128 to decimal.Decimal. There doesn't seem to be a function that can set up the mongo configuration.
Could I make a pull request to add the setRegistry function for the mongo client on https://github.com/zeromicro/go-zero/blob/master/core/stores/mon/options.go?
core/stores/mon/options.go
// WithRegistry the mon client can transfer mongo types to custom types.
func WithRegistry(registry *bsoncodec.Registry) Option {
return func(opts *options) {
opts.SetRegistry(registry)
}
}
To use this function, follow the example below:
registry := bson.NewRegistry()
registry.RegisterTypeEncoder(reflect.TypeOf(decimal.Decimal{}), MongoDecimal{})
// this code
opts := mon.WithRegistry(registry)
conn := mon.MustNewModel(url, db, collection, opts)
试过了还是不行,错误为: cannot decode 128-bit decimal into a decimal.Decimal
registry := bson.NewRegistry() registry.RegisterTypeEncoder(reflect.TypeOf(decimal.Decimal{}), &mongo.MongoDecimal{}) conn := mon.MustNewModel(url, db, collection, mongo.WithRegistry(registry))
func WithRegistry(registry bsoncodec.Registry) mon.Option { return func(opts mopt.ClientOptions) { opts.SetRegistry(registry) } }
mongo.mongoDecimal的代码为: ` package mongo
import ( "fmt" "github.com/shopspring/decimal" "github.com/zeromicro/go-zero/core/stores/mon" "go.mongodb.org/mongo-driver/bson/bsoncodec" "go.mongodb.org/mongo-driver/bson/bsonrw" "go.mongodb.org/mongo-driver/bson/primitive" mopt "go.mongodb.org/mongo-driver/mongo/options" "reflect" )
// MongoDecimal是一个允许十进制编码的ValueCodec,Decimal128到decimal.Decimal type MongoDecimal struct{}
var _ bsoncodec.ValueCodec = &MongoDecimal{}
func WithRegistry(registry bsoncodec.Registry) mon.Option { return func(opts mopt.ClientOptions) { opts.SetRegistry(registry) } }
func (dc *MongoDecimal) EncodeValue(ect bsoncodec.EncodeContext, w bsonrw.ValueWriter, value reflect.Value) error { // 使用反射转换,值改为 decimal.Decimal. dec, ok := value.Interface().(decimal.Decimal) if !ok { return fmt.Errorf("value %v to encode is not of type decimal.Decimal", value) }
// Convert decimal.Decimal to primitive.Decimal128.
primDec, err := primitive.ParseDecimal128(dec.String())
if err != nil {
return fmt.Errorf("error converting decimal.Decimal %v to primitive.Decimal128: %v", dec, err)
}
return w.WriteDecimal128(primDec)
}
func (dc *MongoDecimal) DecodeValue(ect bsoncodec.DecodeContext, r bsonrw.ValueReader, value reflect.Value) error { primDec, err := r.ReadDecimal128() if err != nil { return fmt.Errorf("error reading primitive.Decimal128 from ValueReader: %v", err) }
// 将primitive.Decimal128转变为Golang的decimal.Decimal.
dec, err := decimal.NewFromString(primDec.String())
if err != nil {
return fmt.Errorf("error converting primitive.Decimal128 %v to decimal.Decimal: %v", primDec, err)
}
// 设置值为 decimal.Decimal类型数据
value.Set(reflect.ValueOf(dec))
return nil
}
`
@shanweie
I found a problem that you only use registry.RegisterTypeEncoder
, but there is no registry.RegisterTypeEncoder
.
You have to use BOTH so that you can transfering the Decimal
to MongoDecimal
.
registry := bson.NewRegistry() registry.RegisterTypeEncoder(reflect.TypeOf(decimal.Decimal{}), &mongo.MongoDecimal{})
conn := mon.MustNewModel(url, db, collection, opts)
怎么设置opts,使用registry自动互转