mongoDB学习笔记

时间:2024-04-02 14:20:06

一.为什么选择mongoDB


开源的NoSql数据库。

1.无数据结构限制:没有表结构概念,不需要事先定义表结构就可以使用,每条记录可以有完全不同结构。

mongoDB学习笔记

2.完全的索引支持

mongoDB学习笔记

3.方便的冗余与扩展:复制集保证数据安全,分片扩展数据规模。
4.良好的支持:完善的文档,齐全的驱动支持。


二.mongoDB安装与配置


1.mongoDB运行环境

mongoDB环境:64位linux(也可以是windows环境)

mongoDB版本:2.6.5

ssh工具:xshell

2.编译mongoDB文件

下载mongoDB安装包后放到linux服务器上进行解压并编译

进入解压后的安装文件输入编译命令:scons all (如果机器的CPU有多个,可以这样来加速编译过程 :scons  all  -j  cpu核数)

mongoDB学习笔记

注意:如果编译过程出错可以自行安装所需依赖,如多次编译不能通过,可在官网下载编译好的二进制直接执行。

讲下编译后的几个重要文件:

mongod:mongoDB数据库的执行程序,之后的数据库部署就是使用这个程序进行。

mongo:一个用来链接mongoDB服务器的客户端,之后对数据库的所有操作需要先使用这个客户端连接到mongoDB服务器后才能进行。

mongoimport,mongoexport:用来做mongoDB的导入导出。

mongodump,mongorestore:与上面两个导入导出类似,但导出的是二进制数据,不能被直接读取,一般用来做数据的备份与恢复。

mongoplog:用来做操作日志的回放,是mongoDB复制集中用来记录操作记录的数据集合。

mongostat:用来查看mongoDB服务器的各种状态。

mongoDB学习笔记


3.搭建mongoDB服务器

A.创建安装目录:mkdir mongodb_simple


B.进入安装目录后创建如下文件:

data:用来存储数据库的数据文件。

log:存储数据库的日志文件。

conf:存储数据库的启动配置文件。

bin:存储数据库的二进制文件。


C.将编译好的mongob程序拷贝到bin目录下


D.进入conf文件夹下编辑一个启动文件,命名为mongod.conf

以上ABC三个步骤的命令如下:

mongoDB学习笔记

D.编辑mongod.conf,加入以下参数

port = 12345:指明mongoDB启动时要监控的端口。

dbpath = data : 指明mongoDB数据存储的目录,相对路径和绝对路径都可以。

logpath = log/mongod.log : 指明日志文件的路径。

fork = true : 在linux下表明这是启动了一个后台进程,这个参数在Windows无效。

mongoDB学习笔记


E.启动mongoDB服务器

在安装目录下输入启动命令:./bin/mongod -f conf/mongod.conf   (用-f指明启动时需要使用的配置文件)

mongoDB学习笔记


4.连接mongoDB服务器

A.使用mongoDB编译时生成的客户端进行连接,即mongo客户端。

a.为方便使用,将mongo客户端拷贝到安装目录mongodb_simple的bin目录下,之后可用help命令查看客户端使用说明。

mongoDB学习笔记

b.连接服务器命令:./bin/mongo 127.0.0.1:12345/test  (没有设置用户名和密码所以不需要输入)

mongoDB学习笔记

c.关闭服务命令:db.shutdownServer()   (这个命令只有管理员admin才有权限执行,所以必须先把身份转换为admin)

mongoDB学习笔记


B.使用各种驱动进行连接。


三.mongoDB基本使用


1.数据写入和查询

查询数据库列表:show  dbs

使用数据库:use  xx     (不需要对数据库进行额外创建,mongod会在需要时自己创建数据库)

删除数据库:db.dropDatabase()

写入数据:db.集合名.insert({key:value})    (在mongoDB中将一张表称作一个集合,insert()括号中的参数为要写入的文档,文档格式为json ,即{key:value})

查询表列表 : show collections

查询表中的所有数据:db.集合名.find()

查询表中指定数据:db.集合名.find({key:value})

批量插入数据:for(i=n;i<k;i++)db.集合名.insert({key:i})

查询数据量:db.集合名.find().count()   (skip(n) :过滤掉前n行数据;limit(n):限制返回n条数据;sort({key:value}) : 排序方式)

mongoDB学习笔记

mongoDB学习笔记

mongoDB学习笔记

mongoDB学习笔记


2.数据更新

db.集合名.update(查询条件,更新条件)  (查询条件和更新条件分别为两个json格式的数据)

A.只有一个字段的情况:   

 mongoDB学习笔记 


B.有多个字段时只更新部分字段的情况:更新条件使用set操作符指定修改的字段,未指定的字段不变

mongoDB学习笔记


3.更新不存在的记录

db.集合名.update(查询条件,更新条件,upsert)    (upsert=true表明查找的记录不存在时自动创建一条,默认为false)

mongoDB学习笔记


4.更新多条数据

A.为了防止不小心的update的误操作,在mongoDB中默认只会更新第一条找到的数据

mongoDB学习笔记


B.更新多条记录:db.集合名.update(查询条件,更新条件,upsert,multi)   (multi默认为false表明只更新找到的第一条记录,更新多条记录时设置为true即可)

mongoDB学习笔记


5.数据删除

A.删除表中数据:db.集合名.remove({key:value})

mongoDB学习笔记

B.删除表:db.集合名.drop()

mongoDB学习笔记


6.创建索引

A.查看索引:db.集合名.getIndexes()

mongoDB学习笔记


B.创建索引:db.集合名.ensureIndex({key:value})   (value不再代表值,而是代表方向,1表示正向排序,-1表示逆向排序)

mongoDB学习笔记



四.mongoDB常见的查询索引


1._id索引

_id索引是绝大多数集合默认建立的索引。

对于每个插入的数据,mongoDB都会自动生成一条唯一的_id字段。

2.单键索引

单键索引是最普通的索引,不会自动创建。

值为一个单一的值,例如字符串,数字或者日期等。

mongoDB学习笔记

3.多键索引

多键索引与单键索引都是用db.集合名.ensureIndex({key:value}) 命令创建的。

不同在于多键索引的值具有多个记录,例如数组.

mongoDB学习笔记

插入以上记录后mongoDB便为x创建了一个多键索引。

4.复合索引

当查询条件不只一个时就需要使用复合索引。

mongoDB学习笔记

5.过期索引

A.是在一段时间后会过期的索引。

B.在索引过期后,相应的数据会被删除。


C.适合存储一些在一段时间后会失效的数据如用户的登录信息,存储的日志。


D.创建方法:db.集合名.ensureIndex({time:1},{expireAfterSeconds:value})     (expireAfterSeconds表示过期索引的过期时间,值的单位为秒)

mongoDB学习笔记

E.过期索引的限制:

a.存储在过期索引字段的值必须是指定的时间类型。

必须是ISODate或者ISODate数组,不能使用时间戳,否则不能被自动删除。

b.如果指定了ISODate数组,则按照最小的时间进行删除。

c.过期索引不能是复合索引,因为不能同时指定两个过期时间。

d.删除时间是不精确的。

删除过程是由后台程序每60s跑一次,而且删除也需要一些时间,所以存在误差。


6.索引属性

A.name指定索引名称

db.集合名.ensureIndex({},{name:"    "})

mongoDB学习笔记

mongoDB学习笔记


B.unique指定索引唯一性

db.集合名.ensureIndex({},{unique:true/false})

mongoDB学习笔记


C.sparse指定索引的稀疏性

db.集合名.ensureIndex({},{sparse:true/false})     (默认false表示插入文档时会为索引不存在的字段自动创建索引)

不能在稀疏索引上查找索引字段不存在的记录。

mongoDB学习笔记

mongoDB学习笔记

说明:

$exists操作符用来查找数据集合中一个字段存在或者不存在的记录

当用hint强制使用稀疏索引查找该字段不存在的记录时无法查找到记录


D.expireAfterSeconds指定过期索引的过期时间


五.全文索引


1.创建全文索引的方法

在mongoDB中每个数据集合只能创建一个全文索引。

全文索引与普通索引不同在于value不是1或者-1,而是固定的字符串text。

db.articles.ensureIndex({key:"text"})

db.articles.ensureIndex({key_1:"text",key_2:"text"})

db.articles.ensureIndex({"$**":"text"})    (当有多个key时选用这种方式表示创建一个大的全文索引)

mongoDB学习笔记


2.如何使用全文索引查询

db.articles.find({$text:{$search:"coffee"}})

db.articles.find({$text:{$search:"aa bb cc"}})        (或查询)

db.articles.find({$text:{$search:"aa bb -cc"}})       (-cc表示不包含c)

db.articles.find({$text:{$search:"\"aa\" bb cc"}})   (将字符串用引号包含起来表示与查询,引号前加斜杠为了避免歧义)

mongoDB学习笔记


3.全文索引相似度查询

$meta操作符:{score:{$meta:"textScore"}}

写在查询条件后面可以返回结果的相似度。

与sort一起使用可以达到很好的使用效果

mongoDB学习笔记


4.全文索引的使用限制

A.每次查询只能指定一个$text查询

B.$text查询不能出现在$nor查询中          ($nor查询用来排查某些查询)

C.查询中如果包含了$text,hint不再起作用   (hint可以强制指定索引)

D.mongoDB全文索引还不支持中文


六.mongoDB的地理位置索引


1.2D索引:平面地理位置索引

db.collection.ensureIndex({w:"2d"})    

位置表示方式:经纬度 [经度,纬度]

取值范围:经度 [-180,180]  纬度 [-90,90]

mongoDB学习笔记

查询方式:

A.$near查询:查询距离某个点最近的100个点。可用$minDistance限制返回最大距离的点。

mongoDB学习笔记


B.$geoWithin查询:查询某个形状内的点。

形状的表示:

a.$box:矩形使用

{$box:[[<x1>,<y1>],[<x2>,<y2>]]}

mongoDB学习笔记

b.$center:圆形使用

{$center:[[<x1>,<y1>],r]}

mongoDB学习笔记

c.$polygon:多边形使用

{$polygon:[[<x1>,<y1>],[<x2>,<y2>],[<x3>,<y3>]]}

mongoDB学习笔记


C.geoNear查询:$near查询的进化版

使用runCommand命令进行使用

db.runCommand(

  { geoNear:<collection>,

    near :[x,y],

    minDistance:(对2d索引无效)

    maxDistance:

    num:

 ...}

 )

说明:

geoNear 指定集合的名字

near :指定坐标

num:限制返回的数目

mongoDB学习笔记

说明:

dis:查找到的数据距离指定的坐标 [1,2] 距离多少

obj:查找到的文档

nscanned:扫描了哪些数据

time:花费的时间

maxDistance:最大的距离

avgDistance:平均距离

ok=1代表查询成功


2.2Dsphere索引:球面地理位置索引

db.collection.ensureIndex({w:"2dsphere"})  

位置表示方式:

GeoJSON:描述一个点,一条直线,多边形等形状。

格式:{type:"  " , coordinates:[<coordinates>]}

查询方式与2d索引类似,不同在于2Dsphere索引支持$minDistance


七.索引构建情况分析


索引的优势:加快索引相关的查询

索引的劣势:增加磁盘空间消耗,降低写入性能

如何评判当前索引构建情况:

1.mongostat工具:mongoDB自带的用来查看mongoDB运行状态的程序。(上文我们介绍编译出来的文件时可以看到这个程序)

可通过命令./mongostat --help  查看使用手册

./mongostat -h mongoDB服务器地址:端口号

输出参数介绍

inserts:当前mongoDB的插入数量,数量以每秒为单位

query:查询数量

update:更新的数量

delete:删除的数量

getmore:在进行mongoDB查询时不是每次都返回所有数据,当一次查询比较多的数据时只会返回一定量的数据,当在各种驱动中进行find不停遍历查询时mongoDB会执行getmore用来获取以后的数据。

command:执行命令的数量

flushes:查看mongoDB隔多久会把我们写到内存的数据刷到硬盘上,这个数据比较大时mongoDB的性能会比较差。

mapped,vsize,res:说明mongoDB占据的磁盘空间大小或申请的内存大小

faults:表示如果我们查询的数据没有提前被mongoDB加载到内存中就需要到硬盘上去读取,faults比较高时也会造成性能下降。

locked:锁的使用情况。

idx miss:查询没有命中索引的比例,当这个数据很高时说明索引创建有问题。

qr | qw :mongoDB读队列和写队列的情况,当这两个队列很长时mongoDB的性能会下降。

ar | aw :当前活跃客户端的数据

netIn,netOut:mongoDB使用网卡的输入输出流量

conn:mongoDB的连接数量

mongoDB学习笔记

2.profile集合

profile集合是mongoDB的慢操作日志,在设置合适级别后会将相应操作记录下来

如果profile记录的数据非常大会比较明显降低系统的性能,因此profile一般用于上线前的测试以及刚上线的观察

A.db.getProfilingStatus() : 查看mongoDB当前的profile设置

B.db.setProfilingLevel() : 设置profile的级别    (级别=0时表示不记录任何操作,级别=1时配合slowms做为阈值,mongoDB会记录超过slowns的操作,级别=2时会记录任何操作

C.查看profile集合记录的操作

如db.system.profile.find().sort({$natural:-1}).limit(1)

输出参数介绍:

op:操作类型

ns:查询的命名空间 ,格式为数据库名.profile集合名,如mydb.system.profile

query:find的查询条件

orderby:排序条件

cursorid:游标id,多次getmore的游标id是一样的

ntoreturn:返回的数据量

ntoskip:跳过的数据量

nscanned :扫描的索引数目

nscannedObjects:扫描的实体数目

millis:当前查询使用的时间

mongoDB学习笔记

3.mongoDB日志

可在mongoDB的配置文件mongod.conf配置日志详细程度:verbose = vvvvv    (最多配置5个v,v越多越详细)

4.explain分析

显示出本次查询的详细信息

如db.collection.find({key:value}).explain()

输出参数介绍:

cursor:使用的游标,一般跟索引相关    (cursor=BasicCursor表示没有使用索引)

其他输出字段跟profile集合类似。

mongoDB学习笔记


八.mongoDB安全


1.开启权限认证

A.auth开启

在mongoDB配置文件mongod.conf里配置auth = true 开启权限认证

B.keyfile开启

2.创建用户:createUser(2.6之前为addUser)

输入参数介绍:

user:用户名

pwd : 密码

customData:对用户名,密码的说明,主要用于方便查看

roles:这个用户的角色 (role:角色类型(read读权限,readWrite读写权限,dbAdmin提供对指定数据库的管理权限,dbOwner拥有前面三个权限,userAdmin可以对其他角色的权限进行管理),db:这个角色创建在哪个数据库上)

mongoDB学习笔记


3.用户角色详解

A.数据库角色(read,readWrite,dbAdmin,dbOwner,userAdmin)

B.集群角色(clusterAdmin,clusterManager...)

C.备份角色(backup,restore...)

D.其他特殊权限(DBAdminAnyDatabase)

4.创建用户角色:createRole

输入参数介绍:

_id:唯一的id

role:角色名字

db:数据库的名字

privileges:在数据库上的权限操作

mongoDB学习笔记





B.keyfile开启