如何将Golang big.Int存储到MongoDB中

svdrlsy4  于 2023-11-14  发布在  Go
关注(0)|答案(2)|浏览(105)

我有一个引用 *big. Int的结构体。当将这个结构体简单地存储到MongoDB中时(使用官方驱动程序),当取回结构体时,字段变为nil。将big.Int存储到MongoDB中的正确/最佳方法是什么?

  1. type MyStruct struct {
  2. Number *big.Int
  3. }
  4. nb := MyStruct{Number: big.NewInt(42)}
  5. r, _ := db.Collection("test").InsertOne(context.TODO(), nb)
  6. result := &MyStruct{}
  7. db.Collection("test").FindOne(context.TODO(), bson.D{{"_id", r.InsertedID}}).Decode(result)
  8. fmt.Println(result) // <== Number will be 0 here

字符集
到目前为止,我最好的想法是围绕big.int创建一个实现MarshalBSONUnmarshalBSON的 Package 器(老实说,我甚至不确定如何正确地做)。

yr9zkbsy

yr9zkbsy1#

下面是我提出的一个可能的实现,它将big.Int以纯文本形式存储到MongoDb中。也可以通过使用big.Int的方法BytesSetBytes而不是MarshalText/UnmarshalText轻松存储为字节数组。

  1. package common
  2. import (
  3. "fmt"
  4. "math/big"
  5. "go.mongodb.org/mongo-driver/bson"
  6. )
  7. type BigInt struct {
  8. i *big.Int
  9. }
  10. func NewBigInt(bigint *big.Int) *BigInt {
  11. return &BigInt{i: bigint}
  12. }
  13. func (bi *BigInt) Int() *big.Int {
  14. return bi.i
  15. }
  16. func (bi *BigInt) MarshalBSON() ([]byte, error) {
  17. txt, err := bi.i.MarshalText()
  18. if err != nil {
  19. return nil, err
  20. }
  21. a, err := bson.Marshal(map[string]string{"i": string(txt)})
  22. return a, err
  23. }
  24. func (bi *BigInt) UnmarshalBSON(data []byte) error {
  25. var d bson.D
  26. err := bson.Unmarshal(data, &d)
  27. if err != nil {
  28. return err
  29. }
  30. if v, ok := d.Map()["i"]; ok {
  31. bi.i = big.NewInt(0)
  32. return bi.i.UnmarshalText([]byte(v.(string)))
  33. }
  34. return fmt.Errorf("key 'i' missing")
  35. }

字符集

展开查看全部
woobm2wo

woobm2wo2#

当取回结构体时,该字段变为nil
它返回0的原因是因为big.int没有bsonMap。如果你检查插入MongoDB集合的文档,你应该会看到类似于下面的内容:

  1. {
  2. "_id": ObjectId("..."),
  3. "number": {}
  4. }

字符集
其中number字段中没有存储值。
如何将一个大的.Int存储到MongoDB中?
让我们先了解一下什么是BigInt。大整数数据类型用于整数值可能超出int数据类型支持的范围时。范围为-2^63(-9,223,372,036,854,775,808)到2^63-1(9,223,372,036,854,775,807),存储大小为8字节。通常在SQL中使用。
在Go中,你可以使用更精确的整数类型。可用的built-in types int 8,int 16,int 32和int 64(和它们的无符号对应)最适合数据。Go中大整数的对应是int 64。范围为-9,223,372,036,854,775,808到9,223,372,036,854,775,807,和8字节的存储大小。
使用mongo-go-driver,您可以使用int64,它将被转换为bson RawValue.Int64。例如:

  1. type MyStruct struct {
  2. Number int64
  3. }
  4. collection := db.Collection("tests")
  5. nb := MyStruct{Number: int64(42)}
  6. r, _ := collection.InsertOne(context.TODO(), nb)
  7. var result MyStruct
  8. collection.FindOne(context.TODO(), bson.D{{"_id", r.InsertedID}}).Decode(&result)

展开查看全部

相关问题