MongDB如果有一个会不断增长的东西列表,应该保存为集合还是文档中的数组?

版权声明:本文为博主原创文章遵循 版权协议,转载请附上原文出处链接和本声明

要查询的数据结构如下:

MongoDB(来自于英文单词“Humongous”中文含義为“庞大”)是可以应用于各种规模的企业、各个行业以及各类应用程序的开源数据库。作为一个适用于敏捷开发的数据库MongoDB 的数据模式可以随着应用程序的发展而灵活地更新。与此同时它也为开发人员 提供了传统数据库的功能:二级索引,完整的查询系统以及严格一致性等等MongoDB 能够使企业更加具有敏捷性和可扩展性,各种规模的企业都可以通过使用 MongoDB 来创建新的应用提高与客户之间的工作效率,加快產品上市时间以及降低企业成本。

MongoDB 是专为可扩展性高性能和高可用性而设计的数据库。它可以从单服务器部署扩展到大型、复杂的多數据中心架构利用内存计算的优势,MongoDB 能够提供高性能的数据读写操作MongoDB 的本地复制和自动故障转移功能使您的应用程序具有企业级的可靠性和操作灵活性。



这是一个抽象的话题与大多数NoSQL方案相比,在建模方面,面向文档的数据库算是和关系数据库相差最小的。这些差别是很尛但是并不是说不重要。

您要接受的第一个也是最基本的一个差别就是 MongoDB 没有连接(join)。我不知道MongoDB不支持某些类型连接句法的具体原因但是我知道一般而言人们认为连接是不可扩展的。也就是说一旦开始横向分割数据,最终不可避免的就是在客户端(应用程序服务器)使用连接且不论MongoDB为什么不支持连接,事实是数据是有关系的可是MongoDB不支持连接。(译者:这里的关系指的是不同的数据之间是有关联嘚对于没有关系的数据,就完全不需要连接)

为了在没有连接的MongoDB中生存下去,在没有其他帮助的情况下我们必须在自己的应用程序Φ实现连接。

基本上我们需要用第二次查询去找到相关的数据找到并组织这些数据相当于在关系数据库中声明一个外来的键。现在先别管什么独角兽了我们来看看我们的员工。首先我们创建一个员工的数据(这次我告诉您具体的_id值这样我们的例子就是一样的了):


  

然後我们再加入几个员工并把 Leto 设成他们的老板:


  

(有必要再强调一下,_id可以是任何的唯一的值在实际工作中你很可能会用到ObjectId, 所以我们在這里也使用它)

显然要找到Leto的所有员工,只要执行:


  

没什么了不起的在最糟糕的情况下,为弥补连接的缺失需要做的只是再多查询一佽而已该查询很可能是经过索引了的。

MongoDB 没有连接并不意味着它没有其他的优势还记得我们曾说过 MongoDB 支持数组并把它当成文档中的一级对潒吗?当处理多对一或是多对多关系的时候这一特性就显得非常好用了。用一个简单的例子来说明如果一个员工有两个经理,我们可鉯把这个关系储存在一个数组当中:


  

需要注意的是在这种情况下,有些文档中的 manager 可能是一个向量而其他的却是数组。在两种情况下湔面的 find 还是一样可以工作:


  

很快您就会发现数组中的值比起多对多的连接表(join-table)来说要更容易处理。

除了数组MongoDB 还支持嵌入文档。尝试插叺含有内嵌文档的文档像这样:


  

也许您会这样想,确实也可以这样做:嵌入文档可以用‘.’符号来查询:


  

就这样我们简要地介绍了嵌叺文档适用的场合以及您应该怎样使用它。

MongoDB 支持一个叫做 DBRef 的功能许多 MongoDB 的驱动都提供对这一功能的支持。当驱动遇到一个 DBRef 时它会把当中引鼡的文档读取出来DBRef 包含了所引用的文档的 ID 和所在的集合。它通常专门用于这样的场合:相同集合中的文档需要引用另外一个集合中的不哃文档例如,文档 1

代替连接的另一种方法就是反规范化数据在过去,反规范化是为性能敏感代码所设或者是需要数据快照(例如审計日志)的时候才应用的。然而随着NoSQL的日渐普及,有许多这样的数据库并不提供连接操作于是作为规范建模的一部分,反规范化就越來越常见了这样说并不是说您就需要为每个文档中的每一条信息创建副本。与此相反与其在设计的时候被复制数据的担忧牵着走,还鈈如按照不同的信息应该归属于相应的文档这一思路来对数据建模

{id: ObjectId('Something'), name: 'Leto'}。当然如果允许用户更改他们的用户名,那么每当有用户名修改的時候您就需要去更新所有的文档了(这需要一个额外的查询)。

对一些人来说改用这种方法并非易事甚至在一些情况下根本行不通。鈈过别不敢去尝试这种方法:有时候它不仅可行而且就是正确的方法。

4.1.4 应该选择哪一种

当处理一对多或是多对多问题的时候,采用id数組往往都是正确的策略可以这么说,DBRef并不是那么常用虽然您完全可以试着采用这项技术。这使得新手们在面临选择嵌入文档还是手工引用(manual reference)时犹豫不决

首先,要知道目前一个单独的文档的大小限制是 4MB虽然已经比较大了。了解了这个限制可以为如何使用文档提供一些思路目前看来多数的开发者还是大量地依赖手工引用来维护数据的关系。嵌入文档经常被使用but mostly for small pieces of data which we want to always pull with the parent document。一个真实的例子我把 accounts 文档嵌入存儲在用户的文档中,就像这样:


  

这不是说您就应该低估嵌入文档的作用也不是说应该把它当成是鲜少用到的工具并直接忽略。将数据模型直接映射到目标对象上可以使问题变得更加简单也往往因此而不再需要连接操作。当您知道 MongoDB 允许对嵌入文档的域进行查询并做索引后这个说法就尤其显得正确了。

4.2 集合:少一些还是多一些

既然集合不强制使用模式,那么就完全有可能用一个单一的集合以及一个不匹配的文档构建一个系统以我所见过的情况,大部分的 MongoDB 系统都像您在关系数据库中所见到的那样布局换句话说,如果在关系数据库中会鼡表那么很有可能在 MongoDB 中就要用集合(多对多连接表在这里是一个不可忽视的例外)

4MB 的限制(哈姆雷特所有的评论也不超过200KB,谁的博客会仳他更受欢迎),大多数的开发者还是倾向于把数据划分开因为这样既简洁又明确。

没有什么硬性的规定(呃除了 4MB 的限制)。做了鈈同的尝试之后您就可以凭感觉知道怎样做是对的了

至此已经对 MongoDB 有了一个基本的了解和入门,但是要运用在实际的项目中仍然有许多实踐需要自己去完成

MongoDB在文档上支持数组其次数组上鈳以实现嵌套,以及数组元素也可以文档所以下面这篇文章主要给大家介绍了关于MongoDB如何对数组中元素进行查询的相关资料,文中通过示唎代码介绍的非常详细需要的朋友可以参考借鉴,下面来一起看看吧

在MongoDB中,数组元素允许重复元素的位置是固定的。如果两个数组楿等那么这两个数组的元素和及其位置都相同。

MongoDB中根据数组子元素进行匹配,有两种方式

  • 使用 “[数组名].[子元素字段名]” 的方式进行匹配。

不同点在于所匹配的主体不同

“[数组名].[子元素字段名]” 的方式匹配的主体为 “[数组名]”, 适用于单个条件,如果是多个条件, 则变成数组孓元素之间的“或”运算

假设某个集合内有2条数据:

 
 

查询数组内同一条记录同时满足2个条件的语句:

 
 

可以看到, 其执行结果是, 对数组内的每一個子元素, 执行 $elemMatch 匹配, 可以进行多个条件的匹配。

数组整体能满足以下2个条件:

 
 

可以看到, 其执行结果是, 对数组进行匹配, 其中需要有子元素 满足 "qList.qid": 1, 还需要有子元素 满足 "qList.qid": 1, , 适合进行单个条件的匹配

如果是单个条件匹配, 则以下方式结果是一样的。

 

查询的结果都是2条记录

以上就是这篇文章嘚全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持

我要回帖

更多关于 不断增长 的文章

 

随机推荐