Mongodb体系结构与客户端基本操作及注意细节有哪些

发布时间:2021-11-03 10:33:36 作者:柒染
来源:亿速云 阅读:145

本篇文章为大家展示了Mongodb体系结构与客户端基本操作及注意细节有哪些,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。

说到Mongodb的体系结构,免不了与关系型数据库做个对比。这里以MySQL为例,我们进行一些比较:

从逻辑结构上对比:

MySQL层次概念             MongoDB层次概念

数据库(database)     数据库(database)

表(table)                     集合(collection)

记录(row)                   文档(document)

在MongoDB中没有行、列、关系的概念,集合中的文档相当于一条记录,这体现了模式自由的特点。

从数据存储结构上对比:

MySQL的每个数据库存放在一个与数据库同名的文件夹中,MySQL如果使用MyISAM存储引擎,数据库文件类型就包括.frm、.MYD(存放数据,D为Data)、.MYI(存放索引,I为Index)。

MongoDB的默认数据目录时/data/db,它负责存储所有MongoDB的数据文件。在MongoDB内部,每个数据库都包含一个.ns文件和一些数据文件,而且这些数据文件会随着数据量的增加而变得越来越多,例如系统中有一个叫mydb的数据库,那么构成mydb这个数据库的文件就会有mydb.ns,mydb.0,mydb.1等等组成。

mydb.ns记录了数据库Json对象的命名空间(ns时namespace的缩写),也就是数据库集合里面的命名空间。mydb.0和mydb.1是存放数据库mydb的对象的空间,且大小按照2的n次方大小递增。如mydb.`0的大小是16M,当数据库mydb存满16M之后,就会形成生成mydb.1继续存储,mydb.1的大小为32M,以此类推,随着数据的增加,还会有mydb.2、mydb.3等文件出现,大小64M、128M。默认情况下,现在版本的Mongodb在数据库刚刚建立时就会预先分配好XXX.0和XXX.1共48M空间,之后再随着插入对象的增多而生成后续xxx.2等。

MongoDB客户段基本操作:

首先当然是要确认MongoDB的mongod服务是打开的。详细见我之前的博客。

打开MongoDB客户端的方法时运行MongoDB的bin目录下的mongo。

[neil@neilhost Downloads]$ pstree -p | grep mongod |-mongod(3556)-+-{mongod}(3557) | |-{mongod}(3558) | |-{mongod}(3559) | |-{mongod}(3563) | |-{mongod}(3564) | |-{mongod}(3565) | |-{mongod}(3566) | |-{mongod}(3567) | `-{mongod}(3568) [neil@neilhost Downloads]$ cd /usr/local/mongodb/bin/mongo bash: cd: /usr/local/mongodb/bin/mongo: 不是目录 [neil@neilhost Downloads]$ sudo /usr/local/mongodb/bin/mongo MongoDB shell version: 2.6.8 connecting to: test Welcome to the MongoDB shell. For interactive help, type "help". For more comprehensive documentation, see http://docs.mongodb.org/ Questions? Try the support group http://groups.google.com/group/mongodb-user

接下来介绍几个基本操作,以及一个细节。

show dbs的意思是显示mongodb中所有的数据库。刚安装好mongodb时,默认有两个数据库admin和local,不去管他们。

db指的是当前工作环境所在的数据库。当你每次进入mongo时。默认进入的数据库时test,它是一个隐式存储的数据库,如果需要进入特定的数据库,或是想建立一个新的数据库,只需要“use 数据库名称”就可以了。在mongodb中不需要create database这种操作,想用就用,mongodb会自动帮我们建立了数据库,就像一个服务周到的“黑执事”。这里,我use dt2建立了一个新的数据库dt2,客户端立即现实工作环境转入到dt2。但是,如果你show dbs,发现数据库并没有真正建立。是需要新建表并且插入一些数据才可以吗?不是,只需要你在当前数据库dt2输入任何一个细小的操作命令,如显示当前数据库的集合有哪些,这时候dt2就会被真正建立了。

connecting to: test > show dbs admin (empty) dt1 0.078GB local 0.078GB > db test > use dt2 switched to db dt2 > show dbs admin (empty) dt1 0.078GB local 0.078GB > show collections > show dbs admin (empty) dt1 0.078GB dt2 (empty) local 0.078GB

在上面的命令中,show collections是显示当前数据库下的集合有哪些。因为现在还没有集合,所以什么都不显示。

接下来我们尝试建立集合和插入数据。

> db.student.find() > show collections >

mongodb建立集合(表),依然是一个不需要声明着建立表的过程。即不需要create collection或create table之类操作。

直接用即可。

这里我们依旧首先验证一个小细节。什么样子的表操作才会导致表的生成。通过上面的命令。我们在还没有student集合的时候对其进行查询(find()),但是,之后显示集合的命令可以看到并没有为dt2建立student集合。

于是我直接在student表中插入一个Json对象(存储在Mongodb的单元是Bson对象,在逻辑概念上是一个文档)

> db.student.insert({name:"Viper",age:20}) WriteResult({ "nInserted" : 1 }) > show collections student system.indexes >

这时候,当show collections的时候可以看见,student集合已经有了。这说明在建立集合时,必须想新的集合中插入有效数据,才能真正建立集合。

总结上面的两个细节就是,在MongoDB中建立数据库时,只要use数据库,并且在数据库下执行任何看似不会有任何影响的命令,如查询集合,都会使得数据库建立起来;但是,如果在数据库下,对于新建集合的文档查询是不会导致集合建立的,必须有文档数据插入集合,才能使得集合真正建立起来。这样一对细节很多人未必知道!

另外当空数据库建立集合时,会生成一个索引表,system.indexes。该数据库下的所有集合的ObjectId的索引值全都存放在这里面。

那么下面我们来分别说说增删改查。

前面的例子中其实已经加入了一条文档,这里我们在增加一个文档到student集合。

> db.student.insert({name:"TA",age:18,phone:["1311234567","021-87658765"],GPA:{Math:88,English:99}}) WriteResult({ "nInserted" : 1 }) > db.student.find() { "_id" : ObjectId("54fb0d853fc8173ba3302e6c"), "name" : "Viper", "age" : 20 } { "_id" : ObjectId("54fb10493fc8173ba3302e6d"), "name" : "TA", "age" : 18, "phone" : [ "1311234567", "021-87658765" ], "GPA" : { "Math" : 88, "English" : 99 } } >

这里可以看到,我向mongodb的student集合中插入的两个文档,它们的“表结构”是不一样的。这就是NoSQL数据库与关系型数据库的最重要区别之一(其他区别之前也提过,ACID特性(事务的支持),并发)。

其中第二条文档中我们看到key-value的value可以是一些数、字符串等基本类型外,还可以是数组(其实可以理解为栈,后面的博客文章会介绍value是数组情况下的push和pop,所以理解为一种类似于栈的列表更妥贴),如上面的phone键。更强大的地方是,文档,即插入的Json对象的keybalue的value可以是另一个Json对象,如上面的GPA键。

其实,这些数组、json对象更像是python语法中的列表和字典,哈哈哈哈。。。

这里,我将key-value的value数据类型做个整理:

插入之后的Json对象我们可以看到,新插入的每个文档都被赋予了一个_id,这是可以理解为记录的主,是mongodb自动生存成的key,它的value是一个特定的ObjectId对象,是一个96位二进制数,由机器码、机器进程号、时间、当前命名空间的编号四个部分自动生成,***。当然,如果你愿意,也可以在插入Json对象时自己指定_id的value,只要未发生主键冲突,都可以正常插入。

增加一个记录除了用insert方法之外还有一种方法,那就是save。它的功能是当你指定Json的_id,并且_id在集合中已经存在,那么它会更新相应的文档;否则,则插入一个新的文档。请看下面这个例子,_id的为1的Json对象,***次save是被添加,而第二次则是被更改。

> db.student.find() { "_id" : ObjectId("54fb0d853fc8173ba3302e6c"), "name" : "Viper", "age" : 20 } { "_id" : ObjectId("54fb10493fc8173ba3302e6d"), "name" : "TA", "age" : 18, "phone" : [ "1311234567", "021-87658765" ], "GPA" : { "Math" : 88, "English" : 99 } } > db.student.save({_id:1,name:"happyBKs",age:0}) WriteResult({ "nMatched" : 0, "nUpserted" : 1, "nModified" : 0, "_id" : 1 }) > db.student.find() { "_id" : ObjectId("54fb0d853fc8173ba3302e6c"), "name" : "Viper", "age" : 20 } { "_id" : ObjectId("54fb10493fc8173ba3302e6d"), "name" : "TA", "age" : 18, "phone" : [ "1311234567", "021-87658765" ], "GPA" : { "Math" : 88, "English" : 99 } } { "_id" : 1, "name" : "happyBKs", "age" : 0 } > db.student.save({_id:1,name:"hahaBKs",age:2}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.student.find() { "_id" : ObjectId("54fb0d853fc8173ba3302e6c"), "name" : "Viper", "age" : 20 } { "_id" : ObjectId("54fb10493fc8173ba3302e6d"), "name" : "TA", "age" : 18, "phone" : [ "1311234567", "021-87658765" ], "GPA" : { "Math" : 88, "English" : 99 } } { "_id" : 1, "name" : "hahaBKs", "age" : 2 } >

更改的操作用的是update方法。

用法为: db.collection.update({...},{...})

参数有两个,***个指定要改谁,第二个指定改成什么。

但是事情没有这么简单,请看下面的例子。原本的打算是将名字为hahaBKs的记录增加一个性别字段,但是发现除了_id的所有字段都被覆盖掉了,只剩下了gender。这显然不是我们的预想的结果。

> db.student.find() { "_id" : ObjectId("54fb0d853fc8173ba3302e6c"), "name" : "Viper", "age" : 20 } { "_id" : ObjectId("54fb10493fc8173ba3302e6d"), "name" : "TA", "age" : 18, "phone" : [ "1311234567", "021-87658765" ], "GPA" : { "Math" : 88, "English" : 99 } } { "_id" : 1, "name" : "hahaBKs", "age" : 2 } > > db.student.update({name:"hahaBKs"},{gender:"male"}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.student.find() { "_id" : ObjectId("54fb0d853fc8173ba3302e6c"), "name" : "Viper", "age" : 20 } { "_id" : ObjectId("54fb10493fc8173ba3302e6d"), "name" : "TA", "age" : 18, "phone" : [ "1311234567", "021-87658765" ], "GPA" : { "Math" : 88, "English" : 99 } } { "_id" : 1, "gender" : "male" } >

那么问题出在哪里呢?这里我们需要用到的一个操作符$set,具体的用法以后的文章李会详细来说。

下面我直接给出一个解决办法的示例,如下:

> db.student.insert({name:"TB",age:11,gender:"male",room:"301"}) WriteResult({ "nInserted" : 1 }) > db.student.find() { "_id" : ObjectId("54fb0d853fc8173ba3302e6c"), "name" : "Viper", "age" : 20 } { "_id" : ObjectId("54fb10493fc8173ba3302e6d"), "name" : "TA", "age" : 18, "phone" : [ "1311234567", "021-87658765" ], "GPA" : { "Math" : 88, "English" : 99 } } { "_id" : 1, "gender" : "male" } { "_id" : ObjectId("54fc521d3fc8173ba3302e6e"), "name" : "TB", "age" : 11, "gender" : "male", "room" : "301" } > db.student.update({name:"TB"},{$set:{age:22,classid:"1515"}}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.student.find() { "_id" : ObjectId("54fb0d853fc8173ba3302e6c"), "name" : "Viper", "age" : 20 } { "_id" : ObjectId("54fb10493fc8173ba3302e6d"), "name" : "TA", "age" : 18, "phone" : [ "1311234567", "021-87658765" ], "GPA" : { "Math" : 88, "English" : 99 } } { "_id" : 1, "gender" : "male" } { "_id" : ObjectId("54fc521d3fc8173ba3302e6e"), "name" : "TB", "age" : 22, "gender" : "male", "room" : "301", "classid" : "1515" } >

上面的例子是,增加了一个name叫TB的对象,然后对其进行更改,更改的内容包括,将原有age键的值11改成22,并增加一个新的键classid赋值“1515”。这里需要用到的操作符就是$set,用于设置键的值。

删除的方法是remove。

用法是 db.collection.remove({...})

参数里写明想需要删除的对象的条件。

注意,当参数空着,或者空的Json对象。即db.collection.remove()和db.collection.remove({}),将把该集合中的所有文档全部删除!!!

> db.class.insert({classname:"English",teacher:"Mr A"}) WriteResult({ "nInserted" : 1 }) > db.class.insert({classname:"Math",teacher:"Mr B"}) WriteResult({ "nInserted" : 1 }) > db.class.find() { "_id" : ObjectId("54fc54773fc8173ba3302e6f"), "classname" : "English", "teacher" : "Mr A" } { "_id" : ObjectId("54fc54833fc8173ba3302e70"), "classname" : "Math", "teacher" : "Mr B" } > db.class.remove({classname:"English"}) WriteResult({ "nRemoved" : 1 }) > db.class.find() { "_id" : ObjectId("54fc54833fc8173ba3302e70"), "classname" : "Math", "teacher" : "Mr B" } > > db.class.remove({}) WriteResult({ "nRemoved" : 1 }) > db.class.find() >

上面的例子中新建了一个class集合,并插入两个文档。其中种种,自己看吧。

用法两种

db.collection.find({....}),其中参数是查询对象的条件。如果find()或find({})就是全查,这和remove很类似。

db.collection.findOne({...})和find相似,但是它只会返回***个查询到的符合条件的对象。

  1. > db.class.insert({classname:"English",teacher:"Mr AAA"}) 

  2. WriteResult({ "nInserted" : 1 }) 

  3. > db.class.insert({classname:"English",teacher:"Mr ZZZ"}) 

  4. WriteResult({ "nInserted" : 1 }) 

  5. > db.class.insert({classname:"English",teacher:"Mr WWW"}) 

  6. WriteResult({ "nInserted" : 1 }) 

  7. > db.class.insert({classname:"English",teacher:"Mr SSS"}) 

  8. WriteResult({ "nInserted" : 1 }) 

  9. > db.class.insert({classname:"French",teacher:"Mr SSS"}) 

  10. WriteResult({ "nInserted" : 1 }) 

  11. > db.class.find({}) 

  12. { "_id" : ObjectId("54fc562e3fc8173ba3302e71"), "classname" : "English", "teacher" : "Mr AAA" } 

  13. { "_id" : ObjectId("54fc56373fc8173ba3302e72"), "classname" : "English", "teacher" : "Mr ZZZ" } 

  14. { "_id" : ObjectId("54fc56413fc8173ba3302e73"), "classname" : "English", "teacher" : "Mr WWW" } 

  15. { "_id" : ObjectId("54fc564e3fc8173ba3302e74"), "classname" : "English", "teacher" : "Mr SSS" } 

  16. { "_id" : ObjectId("54fc56603fc8173ba3302e75"), "classname" : "French", "teacher" : "Mr SSS" } 

  17. > db.class.findOne({classname:"English"}) 

  18. "_id" : ObjectId("54fc562e3fc8173ba3302e71"), 

  19. "classname" : "English", 

  20. "teacher" : "Mr AAA" 

  21. > db.class.find({classname:"English"}) 

  22. { "_id" : ObjectId("54fc562e3fc8173ba3302e71"), "classname" : "English", "teacher" : "Mr AAA" } 

  23. { "_id" : ObjectId("54fc56373fc8173ba3302e72"), "classname" : "English", "teacher" : "Mr ZZZ" } 

  24. { "_id" : ObjectId("54fc56413fc8173ba3302e73"), "classname" : "English", "teacher" : "Mr WWW" } 

  25. { "_id" : ObjectId("54fc564e3fc8173ba3302e74"), "classname" : "English", "teacher" : "Mr SSS" } 

  26. >

上述内容就是Mongodb体系结构与客户端基本操作及注意细节有哪些,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注亿速云行业资讯频道。

推荐阅读:
  1. MongoDB的安装与基本操作
  2. [MongoDB] 基本操作

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

mongodb

上一篇:@Resources, @Inject和@Autowired的区别是什么

下一篇:怎么用Python画热力图

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》