mongodb - 如何将 Golang big.Int 存储到 MongoDB 中
问题描述
我有一个引用 *big.Int 的结构。当将此结构天真地存储到 MongoDB 中(使用官方驱动程序)时,该字段在取回结构时变为 nil。将 big.Int 存储到 MongoDB 中的正确/最佳方法是什么?
type MyStruct struct {
Number *big.Int
}
nb := MyStruct{Number: big.NewInt(42)}
r, _ := db.Collection("test").InsertOne(context.TODO(), nb)
result := &MyStruct{}
db.Collection("test").FindOne(context.TODO(), bson.D{{"_id", r.InsertedID}}).Decode(result)
fmt.Println(result) // <== Number will be 0 here
到目前为止,我最好的想法是围绕 big.Int 创建一个实现MarshalBSON
and的包装器UnmarshalBSON
(老实说,我什至不知道如何正确地做到这一点)。但这会很不方便。
解决方案
这是我想出的一个可能的实现,它将 big.Int 作为纯文本存储到 MongoDb 中。也可以通过使用方法Bytes
和SetBytes
big.Int 而不是MarshalText
/轻松存储为字节数组UnmarshalText
。
package common
import (
"fmt"
"math/big"
"go.mongodb.org/mongo-driver/bson"
)
type BigInt struct {
i *big.Int
}
func NewBigInt(bigint *big.Int) *BigInt {
return &BigInt{i: bigint}
}
func (bi *BigInt) Int() *big.Int {
return bi.i
}
func (bi *BigInt) MarshalBSON() ([]byte, error) {
txt, err := bi.i.MarshalText()
if err != nil {
return nil, err
}
a, err := bson.Marshal(map[string]string{"i": string(txt)})
return a, err
}
func (bi *BigInt) UnmarshalBSON(data []byte) error {
var d bson.D
err := bson.Unmarshal(data, &d)
if err != nil {
return err
}
if v, ok := d.Map()["i"]; ok {
bi.i = big.NewInt(0)
return bi.i.UnmarshalText([]byte(v.(string)))
}
return fmt.Errorf("key 'i' missing")
}
推荐阅读
- autohotkey - 在 AutoHotKey 中使用 Ctrl+Shift+Alt
- java - 包...在intellij idea中不存在错误
- javascript - 变量未定义
- flutter - Flutter 无法使用 Speedometer 找到正确的提供程序
- react-native - 错误 - VirtualizedLists 不应该嵌套在具有相同方向的普通 ScrollViews 中
- build - AWS-Amplify 没有更新我在公用文件夹中的 index.html 文件
- android-studio - Android Studio 'Comment with line Comment' 快捷方式不起作用
- apache-kafka - 如何将数据从 Prometheus 泵送到 Kafka?
- webpack - ios:“由于访问控制检查,Fetch API 无法加载”NestJS + Apollo
- php - php 函数来获取数据,将具有公共字段名称的多个表连接起来并显示输出