MongoDB Middle Level (关联多表查询)

DBRef is a more formal specification for creating references between documents.  DBRefs (generally) include a collection name as well as an object id.  Most developers only use DBRefs if the collection can change from one document to the next.  If your referenced collection will always be the same, the manual references outlined above are more efficient.

^_^[root@:/usr/local/mongodb/bin]#./mongo
MongoDB shell version: 1.8.2
connecting to: test
> var a = {name:"C++"}                                                                                           
> db 
test
> db.language.save(a)
> db.language.find()
{ "_id" : ObjectId("4da32c897d2de864e0448e06"), "name" : "C++" }
> var b = {name:"javascript"}
> db.language.save(b)
> db.language.find()
{ "_id" : ObjectId("4da32c897d2de864e0448e06"), "name" : "C++" }
{ "_id" : ObjectId("4da32cb17d2de864e0448e07"), "name" : "javascript" }
> lan = {name:"obj1",computer:[new DBRef('language',a._id)]}
{
        "name" : "obj1",
        "computer" : [
                {
                        "$ref" : "language",
                        "$id" : ObjectId("4da32c897d2de864e0448e06")
                }
        ]
}
> lan.computer[0]
{ "$ref" : "language", "$id" : ObjectId("4da32c897d2de864e0448e06") }
> lan.computer[0].fetch()
{ "_id" : ObjectId("4da32c897d2de864e0448e06"), "name" : "C++" }
> db.language.insert(lan)                                                                                        
> db.language.find()
{ "_id" : ObjectId("4da32c897d2de864e0448e06"), "name" : "C++" }
{ "_id" : ObjectId("4da32cb17d2de864e0448e07"), "name" : "javascript" }
{ "_id" : ObjectId("4da33b487d2de864e0448e08"), "name" : "obj1", "computer" : [ { "$ref" : "language", "$id" : ObjectId("4da32c897d2de864e0448e06") } ] }
> db.language.findOne({name:"obj1"}).computer[0].fetch()                                                         
{ "_id" : ObjectId("4da32c897d2de864e0448e06"), "name" : "C++" }
> lan2 = {name:"obj2",computer:[new DBRef('language',b._id)]}     
{
        "name" : "obj2",
        "computer" : [
                {
                        "$ref" : "language",
                        "$id" : ObjectId("4da32cb17d2de864e0448e07")
                }
        ]
}
> db.language.insert(lan2)
> db.language.find()
{ "_id" : ObjectId("4da32c897d2de864e0448e06"), "name" : "C++" }
{ "_id" : ObjectId("4da32cb17d2de864e0448e07"), "name" : "javascript" }
{ "_id" : ObjectId("4da33b487d2de864e0448e08"), "name" : "obj1", "computer" : [ { "$ref" : "language", "$id" : ObjectId("4da32c897d2de864e0448e06") } ] }
 

相关数据存放在一起,针对性的查询可以消除join,性能比分散存储要高且方便

在关系型数据库中,通过连接运算符可以实现多个表联合查询。而非关系型数据库的特点是表之间属于弱关联,Mongodb作为Nosql代表,其本身特性不建议对多Collection关联处理,不过对于有些需要对多表关联处理的需求,Mongodb也可以实现。主要分为两种方式:简单手工关联和DBRef方式关联

1.简单手工关联

下图表示帖子和用户两个Collection的ER图:

扫描二维码关注公众号,回复: 1320436 查看本文章

首先将authors集合中的用户对象查询出来,放在一个变量author中,代码如下:

Shell代码 复制代码  收藏代码
  1. > author=db.authors.findOne({name:"chenzhou"})   
  2. {   
  3.     "_id" : ObjectId("5030ba7621bdee44765b2147"),   
  4.     "name" : "chenzhou",   
  5.     "email" : "[email protected]"  
  6. }  
> author=db.authors.findOne({name:"chenzhou"})
{
	"_id" : ObjectId("5030ba7621bdee44765b2147"),
	"name" : "chenzhou",
	"email" : "[email protected]"
}

通过用户对象author来获取帖子列表,代码如下:

Shell代码 复制代码  收藏代码
  1. > for(var post=db.posts.find({"author_name":author.name}); post.hasNext();){   
  2. ... printjson(post.next().title);   
  3. ... }   
  4. "Hello Mongodb"  
  5. "Hello World"  
  6. "Hello My Friend"  
> for(var post=db.posts.find({"author_name":author.name}); post.hasNext();){
... printjson(post.next().title);
... }
"Hello Mongodb"
"Hello World"
"Hello My Friend"

2.DBRef方式关联

DBRef就是在两个Collection之间定义的一个关联关系,比如,把CollectionB "_id"列的值存在CollectionA的一个列中,然后通过CollectionA这个列中所存的值在CollectionB中找到相应的记录。

示例:模拟用户发帖的过程,看一看如何将帖子表和用户表建立关联。

步骤1:取得当前用户信息,代码如下:

Shell代码 复制代码  收藏代码
  1. > author=db.authors.find({name:"chenzhou"})[0]   
  2. {   
  3.     "_id" : ObjectId("5030ba7621bdee44765b2147"),   
  4.     "name" : "chenzhou",   
  5.     "email" : "[email protected]"  
  6. }  
> author=db.authors.find({name:"chenzhou"})[0]
{
	"_id" : ObjectId("5030ba7621bdee44765b2147"),
	"name" : "chenzhou",
	"email" : "[email protected]"
}

步骤2:发帖子并做关联,代码如下: 

Shell代码 复制代码  收藏代码
  1. > db.posts.insert({"title":"Hello Mongodb DBRef1",   
  2. ... authors:[new DBRef('authors',author._id)]})   
  3. > db.posts.insert({"title":"Hello Mongodb DBRef2",   
  4. ... authors:[new DBRef('authors',author._id)]})   
  5. >  
> db.posts.insert({"title":"Hello Mongodb DBRef1",
... authors:[new DBRef('authors',author._id)]})
> db.posts.insert({"title":"Hello Mongodb DBRef2",
... authors:[new DBRef('authors',author._id)]})
>

步骤3:通知帖子查找用户信息,代码如下:

Shell代码 复制代码  收藏代码
  1. >  db.posts.find({"title":"Hello Mongodb DBRef1"})[0].authors[0].fetch()   
  2. {   
  3.     "_id" : ObjectId("5030ba7621bdee44765b2147"),   
  4.     "name" : "chenzhou",   
  5.     "email" : "[email protected]"  
  6. }  
>  db.posts.find({"title":"Hello Mongodb DBRef1"})[0].authors[0].fetch()
{
	"_id" : ObjectId("5030ba7621bdee44765b2147"),
	"name" : "chenzhou",
	"email" : "[email protected]"
}

通过这个例子可以看出,DBRef就是从文档的一个属性指向另一个文档的指针。

关于DBRef详细信息,可以参见官网说明:http://docs.mongodb.org/manual/applications/database-references/  

猜你喜欢

转载自qianxunniao.iteye.com/blog/1776313