如何通过golang中的mgo将math/big.Int插入到MongoDB中?

huangapple go评论71阅读模式
英文:

How to insert math/big.Int in mongo via mgo in golang

问题

我有一个包含math/big.Int字段的结构体。我想使用mgo将该结构体保存在mongodb中。在我的情况下,将数字保存为字符串就足够了。

我查看了可用的字段标签,但似乎没有任何标签允许自定义序列化器。我原本期望实现一个类似于encoding/json.Marshaler的接口,但在文档中没有找到这样的接口。

以下是我所需的一个简单示例:

package main

import (
	"labix.org/v2/mgo"
	"math/big"
)

type Point struct {
	X, Y *big.Int
}

func main() {
	session, err := mgo.Dial("localhost")
	if err != nil {
		panic(err)
	}
	defer session.Close()

	c := session.DB("test").C("test")
	err = c.Insert(&Point{big.NewInt(1), big.NewInt(1)})
	if err != nil { // should not panic
		panic(err)
	}

	// 代码按预期运行,但在mongo中字段X和Y为空
}

谢谢!

英文:

I have a struct that contains math/big.Int fields. I would like to save the struct in mongodb using mgo. Saving the numbers as a strings is good enough in my situation.

I have looked at the available field's tags and nothing seams to allow custom serializer. I was expecting to implement an interface similar to encoding/json.Marshaler but I have found None of such interface in the documentation.

Here is a trivial example of what I want I need.

package main

import (
	"labix.org/v2/mgo"
	"math/big"
)

type Point struct {
	X, Y *big.Int
}

func main() {
	session, err := mgo.Dial("localhost")
	if err != nil {
		panic(err)
	}
	defer session.Close()

	c := session.DB("test").C("test")
	err = c.Insert(&Point{big.NewInt(1), big.NewInt(1)})
	if err != nil { // should not panic
		panic(err)
	}

	//  The code run as expected but the fields X and Y are empty in mongo
}

Thnaks!

答案1

得分: 6

类似的接口被命名为bson.Getter

它的实现可能类似于这样:

func (point *Point) GetBSON() (interface{}, error) {
    return bson.D{{"x", point.X.String()}, {"y", point.Y.String()}}, nil
}

如果你感兴趣,还有一个在设置器方面的对应接口:

要使用它,请注意作为参数提供的bson.Raw类型具有Unmarshal方法,因此你可以有一个类似于:

type dbPoint struct {
    X string
    Y string
}

并方便地对其进行解组:

var dbp dbPoint
err := raw.Unmarshal(&dbp)

然后使用dbp.Xdbp.Y字符串将大整数放回到被解组的实际(point *Point)中。

英文:

The similar interface is named bson.Getter:

It can look similar to this:

func (point *Point) GetBSON() (interface{}, error) {
    return bson.D{{"x", point.X.String()}, {"y", point.Y.String()}}, nil
}

And there's also the counterpart interface in the setter side, if you're interested:

For using it, note that the bson.Raw type provided as a parameter has an Unmarshal method, so you could have a type similar to:

type dbPoint struct {
    X string
    Y string
}

and unmarshal it conveniently:

var dbp dbPoint
err := raw.Unmarshal(&dbp)

and then use the dbp.X and dbp.Y strings to put the big ints back into the real (point *Point) being unmarshalled.

huangapple
  • 本文由 发表于 2013年9月3日 04:40:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/18580497.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定