你的mongoDB也要和decimal組CP

眾所周知,浮點數(shù)是很調(diào)皮的

都誰在說顺又,喜歡技術(shù)八卦的你,不可以錯過
浮點計算引發(fā)的血案
Go如何精確計算小數(shù)-Decimal研究-Tidb MyDecimal問題

mongodb/mongo-go-driver中的bson.Decimal128只顧及自家存儲的一畝三分地,看起來干干巴巴赫模、麻麻賴賴…… 大家先不著急盤它,據(jù)說有個俊俏的 github.com/shopspring/decimal狡汉,咱們可以說個媒娄徊。

// 我希望mongo中,讀取數(shù)據(jù)時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的接口怎這么費眼睛呢盆顾?

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市畏梆,隨后出現(xiàn)的幾起案子您宪,更是在濱河造成了極大的恐慌,老刑警劉巖奠涌,帶你破解...
    沈念sama閱讀 222,104評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件宪巨,死亡現(xiàn)場離奇詭異,居然都是意外死亡溜畅,警方通過查閱死者的電腦和手機捏卓,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來慈格,“玉大人怠晴,你說我怎么就攤上這事≡±Γ” “怎么了龄寞?”我有些...
    開封第一講書人閱讀 168,697評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長汤功。 經(jīng)常有香客問我物邑,道長,這世上最難降的妖魔是什么滔金? 我笑而不...
    開封第一講書人閱讀 59,836評論 1 298
  • 正文 為了忘掉前任色解,我火速辦了婚禮,結(jié)果婚禮上餐茵,老公的妹妹穿的比我還像新娘科阎。我一直安慰自己,他們只是感情好忿族,可當(dāng)我...
    茶點故事閱讀 68,851評論 6 397
  • 文/花漫 我一把揭開白布锣笨。 她就那樣靜靜地躺著蝌矛,像睡著了一般。 火紅的嫁衣襯著肌膚如雪错英。 梳的紋絲不亂的頭發(fā)上入撒,一...
    開封第一講書人閱讀 52,441評論 1 310
  • 那天,我揣著相機與錄音椭岩,去河邊找鬼茅逮。 笑死,一個胖子當(dāng)著我的面吹牛判哥,可吹牛的內(nèi)容都是我干的献雅。 我是一名探鬼主播,決...
    沈念sama閱讀 40,992評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼塌计,長吁一口氣:“原來是場噩夢啊……” “哼挺身!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起锌仅,我...
    開封第一講書人閱讀 39,899評論 0 276
  • 序言:老撾萬榮一對情侶失蹤瞒渠,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后技扼,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,457評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡嫩痰,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,529評論 3 341
  • 正文 我和宋清朗相戀三年剿吻,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片串纺。...
    茶點故事閱讀 40,664評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡丽旅,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出纺棺,到底是詐尸還是另有隱情榄笙,我是刑警寧澤,帶...
    沈念sama閱讀 36,346評論 5 350
  • 正文 年R本政府宣布祷蝌,位于F島的核電站茅撞,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏巨朦。R本人自食惡果不足惜米丘,卻給世界環(huán)境...
    茶點故事閱讀 42,025評論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望糊啡。 院中可真熱鬧拄查,春花似錦、人聲如沸棚蓄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至稍算,卻和暖如春典尾,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背邪蛔。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評論 1 272
  • 我被黑心中介騙來泰國打工急黎, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人侧到。 一個月前我還...
    沈念sama閱讀 49,081評論 3 377
  • 正文 我出身青樓勃教,卻偏偏與公主長得像,于是被迫代替她去往敵國和親匠抗。 傳聞我的和親對象是個殘疾皇子故源,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,675評論 2 359