庞玉栋个人博客、人生苦短-我用Python

MongoDB笔记

发布时间:6年前热度: 1641 ℃评论数:

MongoDB简介

MongoDB介绍

MongoDB是面向文档的非关系型数据库,不是现在使用最普遍的关系型数据库,其放弃关系模型的原因就是为了获得更加方便的扩展、稳定容错等特性。面向文档的基本思路就是:将关系模型中的“行”的概念换成“文档(document)”模型。面向文档的模型可以将文档和数组内嵌到文档中。因此,实际中可以用一条数据表示非常复杂的结构。
MongoDB没有预定义模式:文档的键(key)和值(value)不再是固定的类型和大小,而且根据需求要添加或者删除字段变得更容易了。由于没有模式需要更改,通常不需要迁移大量数据。不必将所有数据都放到一个模子里面,应用层可以处理新增或丢失的键。这样开发者可以非常容易地变更数据模型。
实际应用中,随着数据量的增大,数据库都要进行扩展。扩展有纵向扩展和横向扩展。纵向扩展是使用计算能力更强的机器,也是最省力的方法,但是很容易达到物理极限,无论花多少钱也买不到最新的机器了。横向扩展就是通过分区将数据分散到更多的机器上。MongoDB的设计采用横向扩展。面向文档的数据模型使它很容易地在多台服务器之间进行数据分割。还可以自动处理跨集群的数据和负载,自动重新分配文档,以及将用户请求路由到正确的机器上。开发者根本不用考虑数据库层次的扩展问题,需要扩展数据库时,在集群中添加机器即可,MongoDB会自动处理后续的事情。
MongoDB有如上各种特性,但为了达到这些,他也放弃了关系型数据库的某些功能如表连接join和复杂的多行事务。

MongoDB的优势与劣势

优势

快速!基于内存,将热数据存放在物理内存中(不仅仅只是索引和少部分数据),从而提高了整体速度和效率。

高扩展性!MongoDB的高可用和集群架构拥有十分高的扩展性。

自身的FailOver机制!在副本集中,当主库遇到问题,无法继续提供服务的时候,副本集将选举一个新的主库继续提供服务。

JSon格式的数据!MongoDB的Bson和JSon格式的数据十分适合文档格式的存储与查询。

 

劣势

应用经验少!由于NoSQL兴起时间短,应用经验相比关系型数据库较少。

由于以往用到的都是关系型数据库,可能会造成使用者一开始的不适应。

无事务机制!MongoDB本身没有自带事务机制,若需要在MongoDB中实现事务机制,需通过一个额外的表,从逻辑上自行实现事务。

MongoDB基础知识与CRUD

1.文档(document):相当于传统关系型数据库的“行”,但比传统行表示的信息更加复杂。例如:

{"name":"jack","age":18,"sex":"male"}

2.集合(collection):这个在MongoDB中代表一组文档,类似于关系型数据库中的表。但在MongoDB中的表(就是集合)是没有模式的,你可以将完全不同的文档放入同一个集合中.但在实际使用中,为特定集合隐性规定一种模式。注:当集合里没有任何文档时集合其实也是不存在的。当第一个文档插入时,集合就会被创建。 
3.数据库(database):在MongoDB中,一组集合可以组成一个数据库。一个MongoDB实例可以承载多个数据库。每个数据库都有独立的权限控制。在实际应用中,通常,一个应用的所有数据放置在一个数据库中。 
4.数据类型:MongoDB中的文档类似于JSON。JSON是一种简单的数据交换格式,在数据类型方面,只支持:null,布尔,数字,字符串,数组和对象。这几种类型在某些实际应用中表现力还是不够,比如JSON本身不直接支持日期类型,对于数字,JSON本身也没法区分整数和浮点数,更不能区分32位数字和64位数字。为此,MongoDB再保留了JSON的各类特性外,又为其添加了一些数据类型。 
1.null:用于表示空值或不存在的字段。Shell中这样表示:{"x":null} 
2.布尔:有两个值,true和false。Shell中这样使用:{"x":true} 
3.数字:Shell中数字均为64位浮点数,如在Shell中{"x":3.14}{"x":3}这两个文档中的值均是64位的浮点数。 
4.字符串:这个用的最广,Shell中这样表示:{"x":"hello world!"} 
5.日期:这个在数据存储时,存储的是从标准纪元开始的毫秒数,没有存储时区信息。 
6.正则表达式:文档中可以包含正则表达式,采用JavaScript的正则表达式语法即可,Shell中这样表示:{"x":/foobar/i}
7.数组:数组是一组值,既可以表示为有序对象(列表,栈,队列等)也可以表示无序对象(集合),Shell中这样表示一个数组:{"things":["pie",3.14]}。 
8.内嵌文档:把一个文档整个作为另一个文档某一个键对应的值。 
其他包括二进制数据,代码等。

MongoDB入门(Shell基本操作)

shell是一个功能完备的JavaScript解释器,可运行任意的JavaScript程序。这里不做示例。 
MongoDB的默认数据库为"db",该数据库存储在data目录中。 
1.选择数据库

#选择名test数据库
use tset

如果忘记了数据库名称可以输入如下代码查询所有数据库名称:"show dbs" 命令可以显示所有数据的列表

show dbs

查看数据库中的集合名:

show collections

下表列出了 RDBMS 与 MongoDB 对应的术语: 

2017-05-17_170031.png

插入文档

insert函数可将一个文档插入到集合中去。以一个博客举例。先创建一个叫post的变量(JavaScript对象)有三个键和对应的属性。插入代码:

db.blog.insert(post)

批量插入

db.blog.insertMany([{"_id":0},{"_id":1},{"_id":2}])

查询文档

查询代码如下:

db.blog.find()

多出来的"_id"就是MongoDB自动创建的默认为ObjectID类型的对象。在一个集合里,每个文档都由唯一的"_id",确保集合中的每个文档都能被唯一标识,它采用12字节的存储空间,由24个16进制数字组成。

如果插入文档时没有"_id"键,系统会为我们自动创建一个。 

若只想查看一个文档,可以用findOne:

db.blog.findOne()

查询具体的某一个文档那么就要以json的形式添加查询条件,例如:

db.blog.find({"title":"My Blog Post"})

以上实例中类似于 WHERE 语句:WHERE title = 'My Blog Post';

修改文档

如果给博客新增一个评论功能,则需要新增key-value,用于保存评论数组。

post.comments = []

之后用新版本的文档替换旧版本:

db.blog.update({"title":"My Blog Post"},post)

使用修改器:

"$Set":用来指定一个字段的值,若字段不存在,则创建它。

db.users.update({"sex":"male"},{"$Set":{"gift":"happy birthday!"}})
/*这样只会更新一个文档,若要更新多个文档,则需要将update的第四个参数设置为true*/
db.users.update({"sex":"male"},{"$Set":{"gift":"happy birthday!"}},false,true) 

"$inc":用来增加已有键的值,若键不存在,就创建它。(与"$Set"类似,专门用来增加数字的,只能用于整形,长整型,双精度浮点型

db.games.update({"game":"pinball","user":"joe"},{"$inc":{"score":50}}) 

"$push":会向已有的数组末尾加入一个元素,若数组不存在,则创建数组。与"$each"自操作符一同使用可以一次添加多个值。

db.stock.ticker.update({"_id":"1"},{"$push":{"hourly":{"$each":[562.667,562.790,562.123]}}}) 

"$addToSet":可以避免重复插入。若数组内已有相同数据,则不差入。与"$each"自操作符一同使用可以一次添加多个值。

db.users.update({"_id""1},{"$addToSet":{"emails":"joe@gmail.com"}})

"$push":删除数组里的元素.("$pop":将数组看成队列或栈,从两端删除。"$pull":将所匹配到的数组中的值删除,而不是只删除一个)

db.blog.remove({"title":"My Blog Post"})

删除整个集合用drop()

db.blog.drop()

索引

MongoDB使用 ensureIndex() 方法来创建索引。

db.COLLECTION_NAME.ensureIndex({KEY:1})

语法中 Key 值为你要创建的索引字段,1为指定按升序创建索引,如果你想按降序来创建索引指定为-1即可。 

当然也可以给多个字段建立索引

db.col.ensureIndex({"title":1,"description":-1})

管道聚合

MongoDB的聚合管道将MongoDB文档在一个管道处理完毕后将结果传递给下一个管道处理。管道操作是可以重复的。 
表达式:处理输入文档并输出。表达式是无状态的,只能用于计算当前聚合管道的文档,不能处理其它的文档。 
这里我们介绍一下聚合框架中常用的几个操作:

  • $project:修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档。
  • db.article.aggregate(
        { $project : {
            title : 1 ,
            author : 1 ,
        }}
    );
  • $match:用于过滤数据,只输出符合条件的文档。
    db.articles.aggregate( [
    { $match : { score : { $gt : 70, $lte : 90 } } },
    { $group: { _id: null, count: { $sum: 1 } } }
    ] );
  • $limit:用来限制MongoDB聚合管道返回的文档数。
  • db.article.find().limit

  • $skip:在聚合管道中跳过指定数量的文档,并返回余下的文档。
  • db.article.aggregate( { $skip : 5 });

    $group:将集合中的文档分组,可用于统计结果。

      $sort:将输入文档排序后输出。


      下面是Mongodb与Mysql的操作命令的对比: 

      2017-05-05_102256.png

      笔记

      手机扫码访问