美文网首页Golang全靠你了
你的mongoDB也要和decimal组CP

你的mongoDB也要和decimal组CP

作者: Godan | 来源:发表于2020-09-18 00:23 被阅读0次

众所周知,浮点数是很调皮的

都谁在说,喜欢技术八卦的你,不可以错过
浮点计算引发的血案
Go如何精确计算小数-Decimal研究-Tidb MyDecimal问题

mongodb/mongo-go-driver中的bson.Decimal128只顾及自家存储的一亩三分地,看起来干干巴巴、麻麻赖赖…… 大家先不着急盘它,据说有个俊俏的 github.com/shopspring/decimal,咱们可以说个媒。

// 我希望mongo中,读取数据时decimal类型直接解析到decimal.Decimal中
// 写入时,又直接把decimal.Decimal放入到mongo的decimal类型中
type Model struct {
  // 这个VIP积分非常重要,弄错公司就玩完啦~
  // 只有他才配的上 decimal.Decimal (狗头
  VIPScore decimal.Decimal `bson:"vip_score"`
}

这回文档有点不好使啦,只能用google到处搜,到处搜

package mongo

import (
    "fmt"
    "reflect"

    "github.com/shopspring/decimal"
    "go.mongodb.org/mongo-driver/bson/bsoncodec"
    "go.mongodb.org/mongo-driver/bson/bsonrw"
    "go.mongodb.org/mongo-driver/bson/bsontype"
    "go.mongodb.org/mongo-driver/bson/primitive"
)

type Decimal decimal.Decimal

func (d Decimal) DecodeValue(dc bsoncodec.DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
    decimalType := reflect.TypeOf(decimal.Decimal{})
    if !val.IsValid() || !val.CanSet() || val.Type() != decimalType {
        return bsoncodec.ValueDecoderError{
            Name:     "decimalDecodeValue",
            Types:    []reflect.Type{decimalType},
            Received: val,
        }
    }

    var value decimal.Decimal
    switch vr.Type() {
    case bsontype.Decimal128:
        dec, err := vr.ReadDecimal128()
        if err != nil {
            return err
        }
        value, err = decimal.NewFromString(dec.String())
        if err != nil {
            return err
        }
    default:
        return fmt.Errorf("received invalid BSON type to decode into decimal.Decimal: %s", vr.Type())
    }

    val.Set(reflect.ValueOf(value))
    return nil
}

func (d Decimal) EncodeValue(ec bsoncodec.EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
    decimalType := reflect.TypeOf(decimal.Decimal{})
    if !val.IsValid() || val.Type() != decimalType {
        return bsoncodec.ValueEncoderError{
            Name:     "decimalEncodeValue",
            Types:    []reflect.Type{decimalType},
            Received: val,
        }
    }

    dec := val.Interface().(decimal.Decimal)
    dec128, err := primitive.ParseDecimal128(dec.String())
    if err != nil {
        return err
    }

    return vw.WriteDecimal128(dec128)
}

然后呢,需要到ClientOptions注册自定义编码解码

     cli, err := mongo.NewClient(options.Client().ApplyURI("这是个mongoURI连接地址").
            SetRegistry(bson.NewRegistryBuilder().
                RegisterDecoder(reflect.TypeOf(decimal.Decimal{}), Decimal{}).
                RegisterEncoder(reflect.TypeOf(decimal.Decimal{}), Decimal{}).
                Build())
    if err != nil {
        log.Fatal().Err(err).Msg("连接到mongo")
    }

大概就是这样。

另外,我想帮一个朋友问问mongo的接口怎这么费眼睛呢?

相关文章

  • 你的mongoDB也要和decimal组CP

    众所周知,浮点数是很调皮的 都谁在说,喜欢技术八卦的你,不可以错过浮点计算引发的血案 Go如何精确计算小数-Dec...

  • python mongodb decimal

    mongo Shell中的数据类型[https://docs.mongoing.com/the-mongo-she...

  • Kotlin与MongoDB整合CURD案例详解

    1、mongodb的低版本bson无法转换类型 比如MongoDB数据库表的字段类型为Decimal,实体类用St...

  • 青青子衿,悠悠我心--区块链众生相之分野黄金

    大家好,我是小胖尺,一个想成为富婆却至今没有什么钱的小胖子。今天的心情有点激动,昨天有人要和我组CP,CP名字叫小...

  • 健身日记6

    昨天练腿了,碰巧的是我媳妇也练腿。于是我俩便又临时组成了健身cp。真的是做啥都是cp。 你一组我一组的做着史密斯深...

  • Crack5-软件开发:R.A.U 的细菌基因组Genome C

    1. 你的基因组报告数据: 2.工具的构建与对应的代码如下: 对于去除decimal points 以及对应的概念...

  • 关于复制,你了解多少(附副本集常见教程)

    MongoDB Manual (Version 4.2)> Replication MongoDB中的副本集是一组...

  • MySQL PT工具使用

    MySQL 的decimal数据类型 DECIMAL 列的声明语法是 DECIMAL(M,D)。参数值的范围如下:...

  • 组cp

    本人大三,无聊透顶的一个人。不玩游戏,有一颗奋进的❤️。 不分男女,只论美丑。组个cp,无聊时的打发。只想在很多人...

  • 组CP!!!

    留下你们生日,同一天的,就组一天cp啊啊啊啊 !!!! 祝愿你们都早日找到那个意中人。 看看你们会不会遇见你们的那...

网友评论

    本文标题:你的mongoDB也要和decimal组CP

    本文链接:https://www.haomeiwen.com/subject/isqdyktx.html