如何取消引用mgo中的dbref?
Posted
技术标签:
【中文标题】如何取消引用mgo中的dbref?【英文标题】:How to dereference dbref in mgo? 【发布时间】:2015-11-16 04:50:36 【问题描述】: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
)
//尝试10000次插入
id := bson.NewObjectId()
user := &User id, "test"
db.C("users").insert(user)
post := db.C("Post").insert(&PostUid: id.hex(), ref: mgo.DBRef"ref":"users", "id": id, Title:"test dbref")
//第一种方式太脏了-_-!
//mysql: left join users on user.id=post.uid,在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
次要方式,带ref属性,但是mgo.session会尝试findid
for _,m := range posts
db.FindRef(m.ref).One(&m.User)
//第三种方式,使用 mapReduce ??
这是我的第一个 golang + mongodb,那么归档 dbref 或 joins 的最佳方式是什么?
谢谢
【问题讨论】:
这个问题怎么样?我有同样的问题 我想你希望 m.User = u 在那个嵌套循环中。 【参考方案1】:除了使用DBRef,您可以使用manual reference 方法连接两个或多个相关文档。例如,您的结构可以如下所示:
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
然后您可以使用$lookup aggregation stage 执行左外连接。例如,要根据用户查找所有帖子:
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)
示例结果:
"_id": ObjectId("590ab726f4bab950360c2dbe"),
"name": "test",
"posts": [
"_id": ObjectId("590ab72619663bad7743ff9e"),
"userid": ObjectId("590ab726f4bab950360c2dbe"),
"title": "test manual reference"
]
除了将用户和帖子存储在单独的集合中之外,您还可以嵌入/子文档。另见Data Modelling
【讨论】:
注意$lookup
是Mongo 3.2+版本以上是关于如何取消引用mgo中的dbref?的主要内容,如果未能解决你的问题,请参考以下文章
Spring Data MongoDB中的手动引用与DBRef?