《MongoDB管理与开发精要》——3.3节联合查询

3.3 联合查询
通过连接运算符可以实现多个表联合查询。连接是关系型数据库模型的主要特点,也是它区别于其他类型数据库管理系统的一个标志。
在关系型数据库管理系统中,表建立时各数据之间的关系不必确定,常把一个实体的所有信息存放在一个表中。当检索数据时,通过连接操作查询出存放在多个表中的不同实体的信息。连接操作的灵活性给用户带来很大的方便,它们可以在任何时候增加新的数据类型、为不同实体创建新的表,而后通过连接进行查询。
其实由于MongoDB本身的特点,不建议用多collection关联处理,但有些需求必须进行关联处理,因此,我们可以用两种方法去应付这类需求:简单手工关联和DBRef方式关联。

3.3.1 简单手工关联
本小节模拟用户在论坛上查看帖子列表的场景,图3-1是帖子和用户这两个collection的ER图。


a09e81163603cfd6e9428ebf9f7f4bff0dc52aa3

扩展阅读 ER图
ER图(Entity-Relation Diagram,实体联系图)用来建立数据模型,在数据库系统概论中属于概念设计阶段,形成一个独立于机器,独立于DBMS的ER图模型。 通常将它简称为ER图,相应地可把用ER图描绘的数据模型称为ER模型。ER图提供了表示实体(即数据对象)、属性和联系的方法,用来描述现实世界的概念模型。
下面演示如何通过用户名获得该用户发表过的帖子。
步骤1 取得用户对象“u”, 如下面的代码所示:

> u=db.users.findOne({author:"wangwenlong"}) 
{
        "_id" : ObjectId("4fe5624a5339f67c2fdbd129"),
        "author" : "wangwenlong",
        "email" : "wangwenlong@gmail.com"
}
步骤2 通过用户对象“u”来取得帖子列表, 如下面的代码所示:
> for( var p = db.postings.find({author:u.author}); p.hasNext(); ) {
...     printjson( p.next().title);
... }
"Hello MongoDB!"
"Hello China!"
"Hello Beijing!"

上例使用了一个for循环就一次性地将某用户的帖子标题都列出来了。本例中其实两张表并没有显式地定义过任何关系,在下面的例子中将看到另外一种联合查询的方法。
3.3.2 DBRef方式关联
DBRef就是在两个collection之间定义的一个关联,比如,把collectionB“_id”列的值存在collectionA的一个列中,然后通过collectionA这个列中所存的值在collectionB中找到相应的记录。
我们模拟一个用户发帖子的流程,看一看如何将帖子表和用户表建立关联的。
步骤1 取得当前用户信息, 如下面的代码所示:

> db.users.insert({name:"wangwenlong"})
> u1=db.users.find({name:"wangwenlong"})[0]
{ "_id" : ObjectId("4fe5be50c932987b1cf6a095"), "name" : "wangwenlong" }
步骤2 发帖子并做关联, 如下面的代码所示:
> db.postings.insert({"title" : "Hello MongoDB!", 
        users : [ new DBRef('users', u1._id) ] })
> db.postings.insert ({"title" : "Hello China!", 
        users : [ new DBRef('users', u1._id) ] })
步骤3 通知帖子查找用户信息, 如下面的代码所示:
> db.postings.find({title:"Hello China!"})[0].users[0].fetch()
{ "_id" : ObjectId("4fe5be50c932987b1cf6a095"), "name" : "wangwenlong" }

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值