对MongoDB设计模式的理解和常用查询总结

本文介绍了MongoDB的特点,强调其能处理复杂实体关系,并探讨了MongoDB的设计模式,包括嵌入与引用、一对多、多对多和树结构。在查询方面,详细阐述了简单查询和聚合查询的操作符,如范围查询、布尔运算符、数组操作符等,并提到聚合框架中的$project和$group操作。
摘要由CSDN通过智能技术生成

一、MongoDB的特点

mongo的特点一图以蔽之:

这里写图片描述

先说说关系型数据库:

这里的“关系”究竟指的是什么?我们不说大概念和纯理论,只说最实在的东西——关系型数据库中的“表”代表着一类“实体”,实体之间会存在一定关系,比如用户实体和订单实体,一个用户可以有多个订单,而一个订单只属于一个用户,这就是一对多的关系。比如商品和类别,一个商品可以归属多个类别,而一个类别下会有多个商品,这就是多对多的关系。

在关系型数据库中,通过在表中添加存储外键的列来表示这些关系。“主键”阿“外键”阿这些键,本质上就是对一个实体的引用,在一个实体中存储了另一个实体的引用,这样的话,实体之间的关系信息是不是也就有了呢?

这样在查询时,通过主键和外键的关联,就可查询实体与实体间的关系。在修改实体时,由于实体之间的关系仅用引用来表示,所以实体的信息仅存在一处,而引用是不会变的不用修改的,这样也只需修改一处的实体信息即可。

再说说mongo:

mongo的设计目标可不仅仅是简单的键值存储,它也可以做到表达现实世界中纷繁复杂的实体和实体之间的关系,所以它也必须能够处理一对多多对多的关系,那它是如何做到的呢?

mongo中一个实体由一个文档(document)表示。文档的属性值可以是基本类型和引用,就和RDBMS的表的列的值一样,但与之不同的是,文档的属性值还可以是:
(1)另一个完整的文档而非引用
(2)数组,且数组的元素既可以是基本类型和引用,也可以是一个完整的文档

mongo可以利用文档中的数组,无比直观地表示一对多多对多的关系。当然也可以像RDBMS那样,在一个文档中存储另一个文档的键来表示这种关系,只不过不能像RDBMS可以通过基于join的连接查询一次查出这种关系,mongo必须经过两次查询(第一次查出符合查询要求的实体,第二次查出与该实体有关系的其它实体)。

同时由于可以值可以是另一个完整的文档而非引用,使其可以设计反范式的数据模型。

二、mongoDB的设计模式

2.1、嵌入与引用

嵌入:包括文档的属性值是一个完整文档,也包括文档的数组属性的元素是一个完整的文档。
引用:就是指文档的属性值是另一个文档id,或文档的数组实行的元素是另一个文档id。

嵌入是反范式的,而引用是符合范式的设计。
嵌入提供了一些查询的性能优势,而引用提供了更多的灵活性。
选择规则:当子文档从不会出现在父文档以外的环境中时使用嵌入方式,否则在单独的集合里存储子文档。

2.2、一对多

(1)像RDBMS那样,在一个文档中存储另一个文档的键来表示这种关系
(2)利用文档的数组,数组的元素是另一个完整的文档
(3)利用文档的数组,数组的元素是另一个文档的id

2.3、多对多

(1)利用文档的数组,数组的元素是另一个文档的id

2.4、树

树的本质是“级联的一对多关系”。要查询树的话,常规做法是递归地进行一对多的查询。树形数据结构并不是mongo所擅长的,但可以通过一种冗余数据的技巧——物化路径的方式,简化树的查询。

遵循物化路径模式,每个树节点都包含一个path字段,这个字段存储了每个级联节点祖先的ID,根节点path为空。

//根节点
{
  _id: ObjectId("000");
  path: null;
}
//一级节点
{
  _id: ObjectId("111");
  path: 000;
}
//二级节点
{
  _id: ObjectId("222");
  path: 000:111;
}
//...

这样在查询特定子树时,比如要查询上述一级节点下的子树,只需 find({path: /^000/}),

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值