web-dev-qa-db-ja.com

mgoを使用した非構造化MongoDBコレクション

私はGoにとても慣れていません。 mGoの例で見たものから、コレクションをクエリしてそこから読み取るには、構造体に返されるデータを事前に定義する必要があります。

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

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

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

20
kwolfe

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

マップの使用:

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

Mgoに関する限り、 bson.M について特別なことは何もないことに注意してください。ただの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"`
}
47

すべてを地図に保存できます。 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つのタイプ、「ブログ投稿」用に別のタイプなど)を定義し、アクセスする可能性のあるすべての属性を含みます。ユーザードキュメントに電子メールアドレスが割り当てられていない場合は、デコード時に空の文字列(またはより一般的にはゼロ値)が返されます。

2
tux21b