当_id成员的类型仅从bson.ObjectId派生时,它不再映射为ObjectId类型:
import (
"gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
)
type CustomId bson.ObjectId
type Foo struct {
ID1 CustomId `bson:"_id"` // broken
ID2 bson.ObjectId // mapped as expected
}
func main() {
session, _ := mgo.Dial("127.0.0.1")
coll := session.DB("mgodemo").C("foocoll")
doc := Foo{
CustomId(bson.NewObjectId()),
bson.NewObjectId(),
}
coll.Insert(doc)
}_id应该是蒙古族的ObjectId。但事实证明,绳子是被选中的:
蒙戈壳牌:
> db.foocoll.findOne()
{ "_id" : "XvMn]K� �\f:�", "id2" : ObjectId("58764d6e5d4be120fa0c3ab1") } // id2 is OK ...
> typeof db.foocoll.findOne()._id
string // OOps. Should be ObjectId !这可能是有意的,因为bson.ObjectId本身是从字符串派生的。但在这里,这对我们不利。
我们能告诉mgo将_id映射到数据库中的ObjectId吗?
发布于 2017-01-11 17:00:02
发布于 2017-01-11 16:41:39
当你这样做时:
type CustomId bson.ObjectId您正在创建一个新类型,mgo包将不再将其视为/识别为bson.ObjectId ( bson包中的bson.ObjectId类型是“硬编码”)。新类型将有0种方法。
我只想坚持bson.ObjectId。但是,如果仍然希望使用自定义ID类型,则可以在创建CustomId时使用嵌入:嵌入类型为bson.ObjectId的值,并为ID1字段使用inline bson标志:
type CustomId struct {
bson.ObjectId `bson:"_id"`
}
type Foo struct {
ID1 CustomId `bson:",inline"`
ID2 bson.ObjectId
}使用它:
doc := Foo{
CustomId{bson.NewObjectId()},
bson.NewObjectId(),
}这具有CustomId拥有bson.ObjectId所拥有的所有方法的优点,您可以添加新的方法并“覆盖”现有的方法。
另一种选择是为您的interface{}使用接口类型(例如,CustomId ),使用它要“简单得多”:
type CustomId interface{}
type Foo struct {
ID1 CustomId `bson:"_id"`
ID2 bson.ObjectId // mapped as expected
}使用它:
doc := Foo{
bson.NewObjectId(),
bson.NewObjectId(),
}当然,沿着这条路走下去,如果您需要访问包装好的类型断言的bson.ObjectId,就必须使用CustomId。
https://stackoverflow.com/questions/41595577
复制相似问题