2017-01-11 5 views
2

_id部材で型マッピングを適用するには、もはやのObjectId型にマップされていない。そのタイプのみbson.ObjectIdから誘導されたときのMgO

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されているべきです。 しかし、それは文字列を選びだしたことが判明:

モンゴシェル:

> 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自体が文字列から派生しているので、これは、意図することができます。しかし、ここでは、私たちにとっては悪いことです。

データベース内のObjectIdに_idをマップするようmgoに指示できますか?

答えて

3

はモンゴで表現を制御するためにSetterGetterインターフェースを使用します。

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 
} 
+0

ニース。コンパイル可能に編集されています。 – icza

1

あなたが行う場合は、この:

type CustomId bson.ObjectId 

あなたは新しいタイプと(タイプbson.ObjectIdはBSONパッケージに「ハードコードさ」である)/見るもうbson.ObjectIdとしてそれを認識しませんmgoパッケージを作成しています。新しい型は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にすべてのメソッドがあり、新しいメソッドを追加して既存のメソッドを "上書き"できるという利点があります。

別のオプションは、それが多くの "単純" になります使用して、あなたのCustomIdのインターフェイスタイプ(例えばinterface{})を使用することです:

type CustomId interface{} 

type Foo struct { 
    ID1 CustomId  `bson:"_id"` 
    ID2 bson.ObjectId // mapped as expected 
} 

それを使用する:もちろん

doc := Foo{ 
    bson.NewObjectId(), 
    bson.NewObjectId(), 
} 

、この道を踏み出すには、を使用しなければなりません。CustomIdのラップされたbson.ObjectIdにアクセスする必要があります。

+0

埋め込みで、私はfooがCustomIdを知っていなければならない欠点がインライン化されている必要が参照してください。まだ巧妙で、うまくいきます。 – shful

関連する問題