Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mongodb 使用mgo强制执行类型映射_Mongodb_Go_Bson_Mgo - Fatal编程技术网

Mongodb 使用mgo强制执行类型映射

Mongodb 使用mgo强制执行类型映射,mongodb,go,bson,mgo,Mongodb,Go,Bson,Mgo,当_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 expec

当_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应该是Mongo中的ObjectId。 但结果是字符串被选中了:

Mongo Shell:

这可能是有意的,因为bson.ObjectId本身是从字符串派生的。但在这里,这对我们不利

我们可以告诉mgo将_id映射到数据库中的ObjectId吗?

执行此操作时:

type CustomId bson.ObjectId
您正在创建一个新类型,
mgo
包将不再看到/识别它为
bson.ObjectId
(类型
bson.ObjectId
在bson包中是“硬编码的”)。新类型将有0个方法

我会坚持使用
bson.ObjectId
。但如果您仍然需要自定义ID类型,则可以在创建
CustomId
时使用嵌入:嵌入类型为
bson.ObjectId
的值,并使用
inline
bson标志作为
ID1
字段:

type CustomId struct {
    bson.ObjectId `bson:"_id"`
}

type Foo struct {
    ID1 CustomId      `bson:",inline"`
    ID2 bson.ObjectId 
}
使用它:

doc := Foo{
    CustomId{bson.NewObjectId()},
    bson.NewObjectId(),
}
doc := Foo{
    bson.NewObjectId(),
    bson.NewObjectId(),
}
这样做的好处是
CustomId
将拥有bson.ObjectId所拥有的所有方法,您可以添加新方法并“覆盖”现有方法

另一种选择是为您的
CustomId
使用接口类型(例如
interface{}
),使用它会“简单得多”:

使用它:

doc := Foo{
    CustomId{bson.NewObjectId()},
    bson.NewObjectId(),
}
doc := Foo{
    bson.NewObjectId(),
    bson.NewObjectId(),
}
当然,沿着这条路走下去,如果您需要访问
CustomId

的包装的
bson.ObjectId
,您必须使用和界面来控制mongo中的表示:

type CustomId bson.ObjectId

func (id *CustomId) SetBSON(raw bson.Raw) error {
   var v bson.ObjectId
   err := raw.Unmarshal(&v)
   *id = CustomId(v)
   return err
}
func (id CustomId) GetBSON() (interface{}, error) {
   return bson.ObjectId(id), nil
}

美好的通过嵌入,我看到了一个缺点,即Foo必须知道CustomId需要内联。仍然很聪明,而且效果很好。