2013-08-20 30 views
16

私は非常に新しいです。コレクションを照会してから読み込むために、mGoの例で見たことから、構造体に戻ってくるデータを事前に定義する必要があります。mgo付き非構造化MongoDBコレクション

type Person struct { 
    ID  bson.ObjectId `bson:"_id,omitempty"` 
    Name  string 
    Phone  string 
    Timestamp time.Time 
} 

PHPでは、ドキュメントが配列に割り当てられました。 1つのレコードが完全に異なるキーセット(名前や電話を含むことはできませんが電子メールを含むことはできません)を持つことができ、定義済みのクラス/構造体/変数を設定せずに直接アクセスできます。

Go/mGoで同じことを行う方法はありますか?

答えて

37

これを処理する方法は複数あります。

var m bson.M 
err := collection.Find(nil).One(&m) 
check(err) 
for key, value := range m { 
    fmt.Println(key, value) 
} 

bson.Mについての特別なものは何も限りMgOが懸念しているがないこと:マップを使用して

。それはちょうどmap[string]interface{}のタイプで、独自のマップタイプを定義し、それらが異なる値タイプを持っていても、それらをmgoと共に使用することができます。

bson.Dが内部MGOすることが知られているスライスであり、それは、より効率的なメカニズムを提供し、キーの順序を保存する方法を提供することの両方が存在する、:ドキュメントのスライスを使用して

いくつかの状況(例えば、インデックスを定義するとき)でMongoDBによって使用されます。例えば

var d bson.D 
err := collection.Find(nil).One(&d) 
check(err) 
for i, elem := range d { 
    fmt.Println(elem.Name, elem.Value) 
} 

、使用してインラインマップフィールド

あなたがあなたのケーキを持って、あまりにもそれを食べることができるように,inline BSON flagはまた、マップフィールドで使用することができます。つまり、構造体を使用することで、既知のフィールドを操作するのが便利になると同時に、インラインマップを使用して未知のフィールドを処理できるようになります。例えば

:対応するための

type Person struct { 
    ID  bson.ObjectId `bson:"_id,omitempty"` 
    Name  string 
    Phone  string 
    Extra  bson.M `bson:",inline"` 
} 
+0

こんにちはグスタボ、あなたの詳細な答えに感謝します。私は、オプションの属性を処理するための "、"インラインのトリックについては知らなかった。 mgoは本当に素晴らしいソフトウェアです! – tux21b

+0

Find(nil).All(&m)で行うことはできますか? –

2

地図にすべてを保存することができます。 mgo/bsonパッケージは、任意のデータを格納するために使用できるbson.Mデータ型を提供します.MongoDBは強力なスキーマを強制しないため、mgoは内部でbson.M型をすべて内部的に使用します。

データを表示するだけの場合は、bson.Mを使用しても問題ありませんが、一度作業を開始したければ、代わりに構造体の使用を検討する必要があります。それ以外の場合は、プログラムに多くの型アサーションが必要です。たとえば、ドキュメントのタイトル(result["title"])を大文字で印刷するとします。ただbson.Mを使用することにより、あなたのコードは次のようになります。

// is there a title attribute? 
if title, ok := result["title"]; ok { 
    // is it a string? (and not another map or integer or something else) 
    if titleStr, ok := title.(string); ok { 
     // ok, it is a string 
     fmt.Println("Title: ", strings.ToUpper(titleStr)) 
    } 
} 

あなたのプログラムでは、mgoはあなたのための構造体にデータを変換させたときに維持することがはるかに読みやすく、容易になるだろう。その後、同じコードは、のように読むかもしれない:

fmt.Println(strings.ToUpper(result.Title)) 

通常、あなたがなど、「ユーザー」のための(すなわち1種類、「ブログ記事」の他、対処したい文書の種類ごとに1つの構造体の型を定義します)にアクセスする可能性のあるすべての属性が含まれています。ユーザー文書に電子メールアドレスが割り当てられていない場合は、デコード時に空の文字列(またはより一般的にはゼロ値)が返されます。

+0

感謝。私はもう少し詳細な答えも提供しました。マップへのアクセスにタイプアサーションがないことに注意してください。 –

+0

ありがとうございます。欠落しているタイプのアサーションを追加しました。 – tux21b

+0

ようこそ。レコードの場合、この特定のケースは 'result [" title "]。(string)'という単一のショットで扱われているかもしれませんが、あなたのコードと説明はより有益です。 –

関連する問題