1. 文档对象之间的关系

  1. 一对一 (one TO one)
    - 例如: 夫妻 (一个丈夫 对应 一个妻子)
    - 在MongoDB中, 可以通过内嵌文档的形式来体现出一对一的关系

演示:
首先在 my_test数据库中创建一个集合, wifeAndHusband, 并向集合中插入数据

{
	name:"黄蓉",
	husband:{
		name:"郭靖"
	}
> db.wifeAndHusband.find().pretty()
{
        "_id" : ObjectId("6118eb8a47935623a0ff6300"),
        "name" : "黄蓉",
        "husband" : {
                "name" : "郭靖"
        }
}

一个文档对象一旦被嵌入到另一个文档对象中就绝不可能再被嵌入到其他文档对象中,因此可以体现出一对一的关系


  1. 一对多 (one TO many) / 多对一 (many TO one) 例如 :
    - 父母 To 孩子
    - 用户 To 订单
    - 文章 To 评论
  • 也可以通过内嵌文档来映射一对多的关系, 拿文章和评论举例, 一个文章可以包含多个评论, 只需要在文章中添加一个评论属性, 属性中包含的是一个数组, 数组中为多个评论对象
  • **问题**: 评论对于文章来说是可以无限多的, 但当评论中的数据多到一定程度后, 会造成单一数据库内存过大的问题,不利于维护

具体实现:
使用 用户 to 订单 距离

  1. 创建一个集合user, 插入以下数据
> db.user.insertMany([{name:'刘俊熙'},{name:'龙猫不热'}])
> db.user.find()

mongodb 多对多关系 mongodb 一对多_mongodb 多对多关系

  1. 创建订单集合 order,插入数据
db.order.insertOne(
    {
    // 用户 刘俊熙对应的订单
        list:['苹果','香蕉','西瓜']
    }
)

但是这样还不能体现该订单是对应 刘俊熙数据的, 如何处理?

  • 刘俊熙数据的_id的值一起添加到 order集合中, 作为标识
db.order.insertOne(
    {
        list:['苹果','香蕉','西瓜'],
        user_id:ObjectId("6118f452928b3b5423acb15f")
    }
)

db.order.find()

mongodb 多对多关系 mongodb 一对多_数据库_02


通过唯一性的_id作为参照插入到另一个文档对象中, 由此实现 一对多的关系

查询一对多

要求: 查询刘俊熙的订单

db.user.findOne({name:"刘俊熙"})._id

mongodb 多对多关系 mongodb 一对多_升序_03

db.order.find({user_id:db.user.findOne({name:"刘俊熙"})._id})

mongodb 多对多关系 mongodb 一对多_字段_04


  1. 多对多 (manyTO many)
  • 分类 - 商品
  • 老师 - 学生

例如: 在teachers集合中插入以下数据

db.teachers.insert([
    {name:"洪七公"},
    {name:"黄药师"},
    {name:"龟仙人"}

    ]);

db.teachers.find()

那么,要怎么体现出多对多的关系呢?

db.stus.insert([
// 如果, 郭靖既是洪七公的徒弟又是黄药师的徒弟,要怎么在数据库中体现呢? 
    {name:"郭靖"}
])

mongodb 多对多关系 mongodb 一对多_升序_05

体现

db.stus.insert([
    {
     name:"郭靖",
     tech_id:[
     // 添加洪七公的 _id 作为tech_id 的其中一条数据
        ObjectId("61192a9b928b3b5423acb166"),
     // 再把洪七公的 _id 也添加进来
        ObjectId("61192a9b928b3b5423acb167")
     ]
    }
])

运行

mongodb 多对多关系 mongodb 一对多_数据_06


这时候就能体现出 多对多的关系了


2. _sort 和 投影

2.1 _sort 排序

emp集合中执行db.emp.find()

mongodb 多对多关系 mongodb 一对多_升序_07


可以看出, 默认情况下, 查询出来的数据是根据_id 由小到大升序排列

如果我们想要顺序按照工资sal排序要怎么办呢?

  • 在 MongoDB 中使用sort()方法对数据进行排序,sort() 方法可以通过参数指定排序的字段,并使用1-1 来指定排序的方式,其中 1 为升序排列,而 -1 是用于降序排列

语法:
>db.COLLECTION_NAME.find().sort({KEY:1})

代码改变如下:

db.emp.find().sort({sal:1})

mongodb 多对多关系 mongodb 一对多_数据_08


这时候就可以实现sal升序排列的效果了

那么这时候如果我们把代码改成下面这样, 运行结果又会是什么样的呢?

db.emp.find().sort({sal:1,empno:-1})

执行一下,我们来看效果

mongodb 多对多关系 mongodb 一对多_数据_09

解释:

  • 如果在sort()方法中传入多个排序条件, 会先按照最前面的条件进行升序或降序, 如果两条数据的值一样, 则会再运行第二个排序条件
  • 拿上面的代码举例, 在排序的时候, 会先按照sal工资数据升序排列, 如果有两个员工的sal工资相同, 那么就会执行第二个排序条件, 按照empno部门编号降序排列

2.2 投影

在MongoDB中,投影表示仅选择所需要字段的数据,而不是选择整个文档字段的数据。如果某个文档有5个字段,但只要显示3个字段,那么就只选择3个字段吧,这样做是非常有好处的。

MongoDB的find()方法,在 MongoDB 查询文档中此方法接收的第二个可选参数是要检索的字段列表。 在MongoDB中,当执行find()方法时,它默认将显示文档的所有字段。为了限制显示的字段,需要将字段列表对应的值设置为101用于显示字段,而0用于隐藏字段

具有投影的find()方法的基本语法如下:

>db.COLLECTION_NAME.find({},{KEY:1})

emp集合中有以下数据

mongodb 多对多关系 mongodb 一对多_数据库_10


要求: 在查询的时候只显示 enamejob, 其他字段不显示, 代码如下:

> db.emp.find({},{ename:1,job:1})

mongodb 多对多关系 mongodb 一对多_字段_11

这时候如果我们连 _id字段也不想显示要怎么做?
**注意**,在执行find()方法时,始终都会显示_id字段,如果不想要此字段,则需要将其设置为0

> db.emp.find({},{ename:1,job:1,_id:0})

mongodb 多对多关系 mongodb 一对多_数据_12