如何取消引用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?

使用 Mongoose / mongoose-dbref 使用和填充(真实的)DBRef 数组

为啥 MongoDB 文档建议不要使用 DBREF?

MongoDB 数据库引用

了解 MongoDB 中的多对多关系以及如何取消引用集合

MongoDB 学习笔记之 DBRef