var (
type User struct{
Id bson.ObjectId `bson:"_id"`
Name string
}
type Post struct{
Id bson.ObjectId `bson:"_id"`
Uid string
User User
ref mgo.DBRef
Title string
}
)
//try 10000 times inserts
id := bson.NewObjectId()
user := &User{ id, "test"}
db.C("users").insert(user)
post := db.C("Post").insert(&Post{Uid: id.hex(), ref: mgo.DBRef{"ref":"users", "id": id}, Title:"test dbref"})
//first way so dirty -_-!
//mysql: left join users on user.id=post.uid, how to do in mgo ?
posts := new([]User)
db.C("posts").Find(nil).All(posts)
ids := []bson.ObjectId
for _, p := range posts{
ids = append(ids, p.Uid)
}
users := make([]User, len(ids))
db.C("users").Find(bson.M{"_id": {"$in": ids}}).All(users)
//and then set the User attribute?
for _,u := range users {
for _, m := range m{
if m.Uid == u.Id {
m.User = m
}
}
}
secondary way,with ref attribute, but mgo.session will try to findid
for _,m := range posts{
db.FindRef(m.ref).One(&m.User)
}
//3th way, with mapReduce ??
it's my first golang + mongodb, so what is the best way to archive dbref or joins?
Thx
Instead of using DBRef, you can just use manual reference method for connecting two or more related documents. For example your struct can just look as below:
type User struct{
Id bson.ObjectId `bson:"_id"`
Name string `json:"name"`
}
type Post struct{
UserId bson.ObjectId `json:"userid"` // manual ref to User
Title string
}
You can then use $lookup aggregation stage to perform a left outer join. For example, to find out all posts based on users:
pipeline := []bson.M{
bson.M{"$lookup": bson.M{
"from": "posts",
"foreignField":"userid",
"localField":"_id",
"as":"posts",
},
},
}
result := []bson.M{}
err := coll_users.Pipe(pipeline).All(&result)
Example result:
{
"_id": ObjectId("590ab726f4bab950360c2dbe"),
"name": "test",
"posts": [
{
"_id": ObjectId("590ab72619663bad7743ff9e"),
"userid": ObjectId("590ab726f4bab950360c2dbe"),
"title": "test manual reference"
}
]
}
Alternative to storing users and posts in separate collections, you could also embed/sub-document. See also Data Modelling
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With