MongoDB学习记录一

本博客说明:最开始部分是一个运维部署案例模板,给开发安装MongoDB都可以按照这个模板来进行基本部署,中间部分是自己研究其他博客记录部署和授权相关内容,最后部分是网上视频学习相关内容;
www.mongodb.org 下载地址
案例安装一个完整MongoDB所做操作;

开发需要访问suntest数据库
规划先创建一个超级管理员root-------必须在关闭权限模式才能创建超级管理员
然后在给开发创建也给管理员admin只能登陆操作他自己的数据库suntest


1.上传并解压
tar -zxvf mongodb-linux-x86_64-3.0.6.tgz -C /home/
cd /home && mv mongodb-linux-x86_64-3.0.6 mongodb

cd /home/mongodb/ && mkdir -p data/db conf run log
2.添加配置
vim /home/mongodb/conf/mongodb.conf
dbpath=/home/mongodb/data/db
port=27017
fork=true
logappend=true
pidfilepath=/home/mongodb/run/mongo.pid
logpath=/home/mongodb/log/mongodb.log

3.编写启动脚本
cd /home/mongodb && vim start.sh
#!/bin/bash
bin/mongod -f /home/mongodb/conf/mongodb.conf &
4.启动MongoDB
cd /home/mongodb && ./start.sh
检查netstat -anlp |grep 27017
5.创建超级管理员账号
开发需要访问suntest数据库
规划先创建一个超级管理员root-------必须在关闭权限模式才能创建超级管理员
cd /home/mongodb/bin && ./mongo
show dbs;

use admin
db.createUser(
{
user:"root",
pwd:"123456",
roles:[
{role:"userAdminAnyDatabase",db:"admin"},
{role: "hostManager", db:"admin"}
]
}
)
db.auth("root","123456")
show collections 没报错就证明授权成功
备注:给予超级管理员hostManager权限的目的是停掉MongoDB时需要用这个权限db.shutdownServer()

5.开启权限模式
echo "auth = true" >> /home/mongodb/conf/mongodb.conf

6.重启MongoDB
/home/mongodb/bin/mongo---进入shell
use admin
db.shutdownServer()
exit---------------------------退出
备注:商用集群千万不要直接kill -9 pid 可以kill -2 pid或者上面的方式
启动cd /home/mongodb && ./start.sh

7.验证
./mongo 192.168.1.2:27017/admin -uadmin -p123456

8.创建指定用户指定数据库权限
给开发创建也给管理员admin只能登陆操作他自己的数据库suntest

use suntest
db.createUser(
{
user:"admin",
pwd:"123456",
roles:[{role:"readWrite",db:"suntest"}]
}
)
db.auth("admin","123456")
show collections 没报错就证明授权成功

9.插入数据测试
>use suntest

>db.suntest.insert({"name":"铁拐李-A","sex":"男","age":19,"score":60,"address":"深圳","course":["语文","数学","英语","政治"]});

查询验证上面插入的数据
> db.suntest.find();
{ "_id" : ObjectId("5badeee2b88b784642866e01"), "name" : "铁拐李-A", "sex" : "男", "age" : 19, "score" : 60, "address" : "深圳", "course" : [ "语文", "数学", "英语", "政治" ] }
db.suntest.remove({"_id" : ObjectId("5badeee2b88b784642866e01")});
WriteResult({ "nRemoved" : 1 })

10.登陆验证
./mongo 192.168.1.2:27017/suntest -uadmin -p123456


11.查看相关命令
./mongo -u admin -p 123456 --authenticationDatabase admin
use admin
db.system.users.find().pretty()
查看
db.system.roles.find();
查看角色
db.getRole("test",{showPrivileges:true})
查看用户
下面切换到admin下查看刚才创建的用户
> use admin
> show users

查看整个MongoDB全部用户
use admin
> db.system.users.find().pretty()
12.角色授权
db.grantPrivilegesToRole(
{
role:"test",
privileges:[
{
resource:{
db:"wallet",
collection:""
},
actions:["createCollection","dropCollection","convertToCapped"]
}
],
roles:[]
}
)

 

13.删除相关命令
删除角色
use admin
use test
db.dropRole("test")
删除用户
>use admin
>use test
> db.dropUser('test1')
true
还可以使用db.dropAllUsers()删除当前库的所有用户,如下:
>use admin
>db.dropAllUsers()
1
就可以把admin库的所有用户都删除掉;

14.用户密码修改
利用db.changeUserPassword()可以修改用户的密码,如下:
db.changeUserPassword('admin','123')


注意:在MongoDB中删除库和集合并不会级联删除对应的角色和用户,如果想要彻底删除对应的业务库,应该先删除库及对应的角色和用户。
如果既想实现精细化权限,又想简化用户管理,原则上可以给开发创建一个账户,并且使用admin做认证库,这样可避免清理过期业务库而导致无法登陆的问题;

 


中间部分
1.MongoDB权限介绍
MongoDB3之前的权限控制简单粗暴,只能给开发提供最高权限,从MongoDB3开始在权限控制这块已完善很多;
1.1关键字理解如下:
user:用户,用于提供客户端连接MongoDB的认证账户;
role:角色,数据权限的集合,创建用户的时候必须指定对应的角色,否则用户无法操作数据库;
resource:资源,包括database或collection也可以是database和collection的组合;例如:{db:<database>,collection:<collection>},当然也可能看到一种特殊的资源:{"cluster":true},表示全局资源;
actions:权限操作,定义了"user"能够对"resource ;document"执行的操作,例如:增删改查包括如下操作:find/insert/remove/update;
privilege:权限,是一组"resource"和"actions"的组合;
authenticationDatabase:认证库,即创建角色或用户时所在的库;例如在admin下创建了MongoDB用户,那么登陆的时候需要执行认证库;
1.2用户角色说明
角色就是对某一资源权限的"集合",MongoDB中有两种角色,一种是知道的角色,一种是自定义的角色;
1.2.1内置角色介绍
A:read:数据库只读权限,包括如下:
aggregate,checkShardingIndex,cloneCollectionAsCapped,collStats,count,dataSize,dbHash,dbStats,distinct,filemd5,mapReduce(inline output only),text(beta feature)geoNear,geoSearch,geoWalk,group;

B:readWrite:数据库的读写权限,包含read角色的所有权限,包括如下:
cloneCollection(as the target database),convertToCapped,create(and to create collections inplicitly),renameCollection(within the same database)findAndModify,mapReduce(output to a collection),drop(),dropIndexes,emptycapped,ensureIndex();

C:dbAdmin:数据库的管理权限,包括如下:
clean,collMod,collStats,compact,convertToCappe,create,db.createCollection(),dbStats,drop(),dropIndexes,ensureIndex(),indexStats,profile,reIndex,renameCollection(within a single database),validate;

D:userAdmin:数据库的用户管理权限;

E:clusterAdmin:集群管理权限(副本集、分片、主从等相关管理);

F:readAnyDatabase:任何数据库的只读权限,和read相似,区别这里是全局的;

G:readWriteAnyDatabase:任何数据库的读写权限,和readWrite相似,这里是全局的;

H:userAdminAnyDatabase:任何数据库的管理权限,与dbAdmin相似,这里是全局的;

I:dbAdminAnyDatabase:任何数据库的管理权限,dbAdmin相似,这里是全局的;

J:backup、restore:数据的备份和恢复权限;

K:root:超级用户权限,只能针对admin库;

1.2.2自定义角色
正常情况下MongoDB内置角色就够用了,当内置角色不能满足需求时可以自定义角色
自定义角色语法如下:
use admin-----------------------------------------------------#进入admin数据库;
db.createRole(
{
role:<role_name>,------------------------------------#定义角色的名称
privileges:[-----------------------------------------#权限集
{resource:{db:<db_name>,collection:<coll_name>},-#定义这个据说要控制的库和集合,集合为""时表示全部;
actions:[----------------------------------------#定义对这个库或集合可进行的权限操作,这里是一个数组;
<action_name>
]
}
],
Roles:[{role:<role_name>,db:<db_name>}]--------------#是否继承其他的角色,如果指定了其他角色那么新创建的角色自动继承对应其他角色的所有权限,该参数必须显示指定;
}
)
}

)
举例说明如下:
use admin
db.createRole(
{
role:"test",
privileges:[
{resource:{
db:"wallet",
collection:""
},
actions:["find","insert","remove","update"]
}
],
roles:[]
}
)
解释:上述语句在admin库里创建了一个名为test的角色,该角色具有对数据库wallet下的所有集合进行find,insert,remove,update的操作权限。角色创建完毕后MongoDB会在系统库admin下创建一个系统collection名叫system.roles,里面存储的即是角色相关的信息,可以使用如下语句进行查看
db.system.roles.find();
1.3操作角色
以下操作都基于admin库
A:查看角色
db.getRole("test",{showPrivileges:true})

B:角色继承
设置角色test1继承test:
db.grantRolesToRole("test1",["test"])
基于test角色移除test1角色
db.revokeRolesFromRole("test1",["test"])

C:角色授权
db.grantPrivilegesToRole(
{
role:"test",
privileges:[
{
resource:{
db:"wallet",
collection:""
},
actions:["createCollection","dropCollection","convertToCapped"]
}
],
roles:[]
}
)

D:角色移权
db.revokePrivilegesFromRole(
{
role:"test",
privileges:[
{
resource:{
db:"wallet",
collection:""
},
actions:["createCollection","dropCollection","convertToCapped"]
}
],
roles:[]
}
)

E:删除角色
db.dropRole("test")

2.mongodb单实例认证
装好MongoDB之后一定不要在配置中加auth=true,做好授权账号密码之后再开启用户认证;
原因如下:
MongoDB安装时不添加任何参数,默认没有权限验证,登陆用户可以对数据库任意操作,刚安装完毕时MongoDB都默认有一个admin数据库,此时admin数据库是空的,没有记录权限相关信息,当admin.system.users一个用户都没有时,这时mongod启动时配置文件中加了auth = true认证就麻烦了;
因为MongoDB的访问分为认证和授权,所以使用auth参数开启认证后,虽然还可以不进行认证直接进入数据库,但是不会有任何权限进行操作,当执行命令时会报如下错误:
not authorized on admin to execute command
一旦开启认证后授权就会生效,如果登陆时没进行用户认证,那么就没有任何权限执行任何命令。

异常处理:出现上述说的第一次装好启动时就设置auth = true认证之后可以处理的方式有如下两种:
方法一:
关掉MongoDB,先添加完用户再开启用户认证;
方法二:
MongoDB提供了一个参数在开启认证的情况下允许本地连接MongoDB,就是使用localhost连接,其余一律不接受,此时把这两个参数同时使用上即可尅器认证时没有添加任何用户的情况下允许本地五人制连接进行数据库操作:
auth = true
SetParameter=enableLocalhostAuthBypass=1
注意:上面两个参数使用有如下条件限制:
A:这个参数值能在开启认证的情况,并且没有任何用户的情况下才生效,否则无效;
B:满足第一个条件时,只允许本地以localhost的方式进行连接MongoDB,否则无效;
C:满足第一个条件时,当进入到MongoDB后如果创建了一个用户后,此参数将失效,就是本地无法登陆了;
D:以此方式创建的用户必须是admin库的,同时必须能够具备创建其他用户的权限;

在MongoDB授权时需要注意版本兼容问题:
admin数据库中的用户名可以管理所有数据库,其他数据库中的用户只能管理其所在的数据库;在2.4版本之前用户的权限分为只读和拥有所有权限,2.4版本的权限管理主要分为:数据库的操作权限、数据库用户的管理权限、集群的管理权限,建议由超级用户在admin数据库中管理这些用户。

3.MongoDB复制集认证
注意:开启KeyFile认证之后无需再开启auth认证;

这里所说的就是在MongoDB集群中认证方式;在复制集机制下开启auth = true认证后,MongoDB复制集状态会变成不健康状态,这就需要梁歪以这个认证方式"KeyFile";简单来说"KeyFile"就是用在复制集群间开启认证的情况下需要的另外一种认证方式,用来验证集群间身份;在复制集模式下开启KeyFile之后就不需要再开启auth了,因为开启KeyFile后就会自动开启认证功能。
开启KeyFile的方法:需要在每个节点主机上创建一个文件,然后给一些字符串,但是复制集各个节点上的字符串必须相同才能进行身份验证,如下方法生成一个KeyFile:
#echo "this is a keyfile" > /usr/local/mongodb/.KeyFile
生成KeyFile时需要注意,不用在意空格、tab、以及换行符,KeyFile会自动去掉;
KeyFile注意事项:
A:内容:base64编码,所以不能超出这个范围[a-zA-Z+/]
B:长度:1000bytes
C:权限:chmod 600 KeyFile
KeyFile生成好之后,就可以同步到各个节点间了,然后在各个节点的配置文件中把KeyFile文件制定进来即可
keyFile=/usr/local/mongodb/.KeyFile
SetParameter=enableLocalhostAuthBypass=1
然后给权限600即可
#chmod 600 /usr/local/mongodb/.KeyFile

再次提醒注意:开启了KeyFile后就不需要添加auth=true参数了,默认会开启认证;然后重启复制集各个节点就完成认证;

在复制集模式下,在整个认证配置完成之前不要创建任何用户,当整个认证好了之后,下面再创建用户;

4.MongoDB创建和删除用户
下面所有内容都是MongoDB3.0+以上版本
4.1不开启认证进行用户创建
4.1.1创建用户并启动
首先需要我们在不认证的情况下,在admin库中创建一个高权限用户,也就是需要在不认证情况下启动MongoDB,下面给出一个简单的配置文件
#/usr/local/mongodb/conf/mongodb.conf
dbpath=/usr/local/mongodb/db
port=27017
fork=true
logappend=true
#auth = true
pidfilepath=/usr/local/mongodb/run/mongo.pid
logpath=/usr/local/mongodb/log/mongodb.log

#mkdir -p /data/db
#chown mongod.mongod /usr/local/mongodb/db -R

启动MongoDB
# ./mongod -f /usr/local/mongodb/conf/mongodb.conf
about to fork child process, waiting until server is ready for connections.
forked process: 40969
child process started successfully, parent exiting
4.1.2打开mongo shell
#/usr/local/mongodb/bin/mongo
接着在命令窗口中输入:
> show dbs
local 0.078GB
看到只有一个local数据库,admin是不存在的(这是3.0以上版本改变了的),我们需要自己给他创建个admin数据库。

4.1.3添加管理用户
> use admin
switched to db admin
>db.createUser(
{
user:"admin",
pwd:"123456",
roles:[{role:"userAdminAnyDatabase",db:"admin"}]
}
)
下面是执行成功后显示出来的内容
Successfully added user: {
"user" : "admin",
"roles" : [
{
"role" : "userAdminAnyDatabase",
"db" : "admin"
}
]
}

user:指定用户名
pwd:指定用户密码
roles:指定角色名称以及角色的认证库

4.1.4查看用户
下面切换到admin下查看刚才创建的用户
> use admin
> show users
{
"_id" : "admin.admin",
"user" : "admin",
"db" : "admin",
"roles" : [
{
"role" : "userAdminAnyDatabase",
"db" : "admin"
}
]
}
或者这样查询也可以
> db.system.users.find().pretty()
{
"_id" : "admin.admin",
"user" : "admin",
"db" : "admin",
"credentials" : {
"SCRAM-SHA-1" : {
"iterationCount" : 10000,
"salt" : "eosukXNkKY0aVWsZ18Dz4Q==",
"storedKey" : "L3okXSu5LDP/Lxpr6LYwwBMkKVc=",
"serverKey" : "IanvYr6fiD4RzjbF9TuN8omIvZA="
}
},
"roles" : [
{
"role" : "userAdminAnyDatabase",
"db" : "admin"
}
]
}

4.1.5关闭MongoDB
千万不要kill -9 pid,可以kill -2 pid或db.shutdownServer()

4.2开启认证,进行用户认证
4.2.1使用auth参数启动MongoDB
当创建完一个高权限用户后就可以开启认证了,在配置文件中添加参数auth参数,然后重启mongod
#echo "auth = true" >> /usr/local/mongodb/conf/mongodb.conf

重启MongoDB
/usr/local/mongodb/bin/mongo
> use admin
switched to db admin
> db.shutdownServer()
> exit
/usr/local/mongodb/bin/mongod -f /usr/local/mongodb/conf/mongodb.conf

4.2.2打开mongo shell进行认证
/usr/local/mongodb/bin/mongo
进行认证,需要注意文明在那个库创建的用户就需要在那个库进行认证;
认证方法一:
> use admin
> db.auth("admin","123456")
1 -------认证,返回1表示成功
认证方法二:
#/usr/local/mongodb/bin/mongo -u admin -p 123456 --authenticationDatabase admin


此时认证完毕之后查看下面的会报错,原因是用户admin只有用户管理的权限;
> show collections
2018-09-07T14:37:53.049+0800 E QUERY Error: listCollections failed: {
"ok" : 0,

4.2.3创建用户
下面创建用户,用户都跟着库走,创建用户test1案例如下
use test -----这个是进入test库,也是新建给test数据库
db.createUser(
{
user:"test1",
pwd:"test1",
roles:[
{role:"readWrite",db:"test"}
]
}
)
创建成功的标志
Successfully added user: {
"user" : "test1",
"roles" : [
{
"role" : "readWrite",
"db" : "test"
}
]
}

4.2.4查看刚才创建的用户
> show users
{
"_id" : "test.test1",
"user" : "test1",
"db" : "test",
"roles" : [
{
"role" : "readWrite",
"db" : "test"
}
]
}

4.2.5查看整个MongoDB全部用户
use admin
> db.system.users.find().pretty()
{
"_id" : "admin.admin",
"user" : "admin",
"db" : "admin",
"credentials" : {
"SCRAM-SHA-1" : {
"iterationCount" : 10000,
"salt" : "eosukXNkKY0aVWsZ18Dz4Q==",
"storedKey" : "L3okXSu5LDP/Lxpr6LYwwBMkKVc=",
"serverKey" : "IanvYr6fiD4RzjbF9TuN8omIvZA="
}
},
"roles" : [
{
"role" : "userAdminAnyDatabase",
"db" : "admin"
}
]
}
{
"_id" : "test.test1",
"user" : "test1",
"db" : "test",
"credentials" : {
"SCRAM-SHA-1" : {
"iterationCount" : 10000,
"salt" : "Ha9L2oBgzfsg4E4NmqK2EQ==",
"storedKey" : "91tlI5351t6yLjsufxifxEXzFTw=",
"serverKey" : "NV7YRm7230NMsWGPHD0VnhLpOrg="
}
},
"roles" : [
{
"role" : "readWrite",
"db" : "test"
}
]
}

4.2.6验证
创建完毕之后验证
> use test
switched to db test
> db.auth("test1","test1")
> show collections 没报错就证明授权成功

5.查看用户
> use admin
switched to db admin
> db.getUser("admin")
{
"_id" : "admin.admin",
"user" : "admin",
"db" : "admin",
"roles" : [
{
"role" : "userAdminAnyDatabase",
"db" : "admin"
}
]
}
6.用户密码修改
利用db.changeUserPassword()可以修改用户的密码,如下:
db.changeUserPassword('admin','123')

7.删除用户

提醒:
修改和删除用户等操作,都和创建用户一样,需要先切换到数据库管理员的身份,即admin库,之后才能进行后面的操作,同样需要到对应数据库中才能删除掉用户,因为用户是跟着库走的;

使用db.dropUser(<user_name>)进行指定用户删除
>use admin
>use test
> db.dropUser('test1')
true
还可以使用db.dropAllUsers()删除当前库的所有用户,如下:
>use admin
>db.dropAllUsers()
1
就可以把admin库的所有用户都删除掉;

注意:在MongoDB中删除库和集合并不会级联删除对应的角色和用户,如果想要彻底删除对应的业务库,应该先删除库及对应的角色和用户。
如果既想实现精细化权限,又想简化用户管理,原则上可以给开发创建一个账户,并且使用admin做认证库,这样可避免清理过期业务库而导致无法登陆的问题;

查看
./mongo -u admin -p 123 --authenticationDatabase admin
use admin
db.system.users.find().pretty()

 

 

 

最后部分
本记录为网上学习MongoDB入门课程笔记;
dos里面清屏cls
1.概念
MongoDB在数据库发展初期就已经存在了,SQL语句使用简单,就是几个简单的单词:select,from,where,group by,having,order by;
NoSQL:not only sql
数据库读取流程:数据读取----POJO(VO、PO)----控制层转化为json数据----客户端
上面这样的数据转换为json比较麻烦,使用MongoDB这种NoSQL数据库直接存放json数据,取出来就是json数据,无需转换可直接使用;NoSQL负责数据的读取;NoSQL按照指定的结构进行存储数据;
概念之关系型数据库和NoSQL比较:
关系型数据库(mysql&oracle) NoSQL数据库
数据库 数据库(类似语句MySQL)
表 集合
行 文档
列 成员
主键 Object ID(自动维护)


所有的NoSQL数据库中MongoDB是发展最好的,因为MongoDB数据库与Node.JS捆绑在一起了,即要从事Node.JS的开发,就一定要用到MongoDB,而Node.JS(基于JavaScript)在国内比较流行;
MongoDB是面向集合的存储过程、模式自由(无模式)、方便的进行数据存储扩容、支持索引、支持短暂数据保留、具备完整的数据库状态监控、基于BSON应用。国内最成功的应用是淘宝;
2.MongoDB的安装和配置
2.1下载:www.mongodb.org
版本介绍:3.0.x变成了windows安装版;这里只是把原来的2.6.4解压缩版本变成了安装拷贝,原来的mongodb-win32-i386-2.6.4zip直接下载打开即可使用;现在都3.0.x安装版安装之后和原来的2.6.4解压缩版解压之后一样;------纠正,目前官网已经更新分不同系统

2.2安装:安装的时候需要选择对应的操作系统;这个软件是夸操作系统的,使用那个版本都可以;Linux上面启动后有个守护进程,这个守护进程在windows上面没有;
windows安装3.0版本:安装选择下一步----选择"custom"-----E:\MongoDB\-----安装完成----备注:如果是2.6.4解压之后和这里安装好之后一样,所以2.6.4直接解压之后使用即可;
配置环境变量:选择"计算机"右键选择"属性"-----"高级系统设置"----"环境变量"-----选择"系统变量"下的"Path"------变量值这里填写E:\MongoDB\bin;放到最前面
2.3启动MongoDB:
启动的前提条件是先在E:\MongoDB目录下建立一个db文件夹;启动之后的数据都放到这个db文件夹下;启动使用的程序是mongod.exe,商用需要启动对应的参数:端口号、是否启用用户验证、数据文件的位置等等。
在E:\MongoDB\目录下建立一个mongodb.conf文件,在这个文件中写上配置内容;
在E:\MongoDB\目录下建立一个log目录,在log目录下建一个文件为mongodb.log
下面编写配置mongodb.conf
# 设置数据目录路径
dbpath = E:\MongoDB\db
# 设置日志信息文件路径,本行设置和下一行设置共同决定是否需要将日志输出到mongodb.log中
logpath = E:\MongoDB\log\mongodb.log
# 打开日志输出操作
logappend = true
# 是否需要登陆认证noauth = true表示不需要登陆认证,在以后进行用户管理使用
noauth = true
# 端口号设置
port = 27001

重启步骤:
进入到MongoDB的shell界面下之后执行如下三步命令即可
A:切换到admin数据库:use admin
B:关闭数据库服务:db.shutdownServer()
C:启动服务:mongod -f e:\MongoDB\mongodb.conf

这时连接方式:mongo --port=27001


启动方式一:不设置端口号启动MongoDB服务
mongod --dbpath E:\MongoDB\db -----这时启动的时候就使用它默认端口号27000
启动方式二:设置端口号启动MongoDB服务(商用)
mongod --dbpath E:\MongoDB\db --port=27000
2.4连接MongoDB
cmd-----mongo进行连接或者指定端口号mondo --port=27000出现如下命令为正常连接
MongoDB shell version:3.0.3
connecting to:test -----进来就默认连接到test这个数据库
2.5MongoDB命令
MongoDB命令区分大小写,很多和mysql一样;
查询有那些数据库show databases;会看到没有数据库,这时制存在一个local的本地数据库,这个数据库不使用;

3.MongoDB基础操作
MongoDB里面有数据库的概念,但是没有模式(所有的信息都按照文档进行保存),数据结构就是json数据结构;只有在进行一些数据处理时才会使用到MongoDB自己的操作符合;
3.1使用mldn数据库
use mldn
实际在这个时候并不会创建数据库,只有在数据库里面保存集合数据之后
3.2创建集合[正常不这样使用]
演示创建一个emp集合:db.createCollection("emp");
正常使用方式是直接往里面存放数据,不是先创建数据库,然后再往数据库里面存数据,因为MongoDB是无模式的;这里我直接向里面保存一个数据:db.dept.insert({"deptno":10,"dname":"财务部","loc":"北京"});

这里可以随意扩充数据
3.3查看所有集合
查询show collections;
这时会看到dept集合自动创建了;

3.4查看emp表的数据
语法:db.集合名称.find({若干条件})
db.dept.find(); ---不写条件时这样查询
查看单独的一个数据:db.dept.findOne();
3.5增加不规则数据
var deptData = {
"deptno":20,
"dname":"研发部",
"loc":"深圳",
"count":20,
"avg":8000.0
};
db.dept.insert(deptData);
直接执行上面的内容即可插入数据;再次查看show collections;
因为可以随意的添加数据,集合结构没有要求,所以MongoDB中没有查看集合结构的命令,MongoDB是无模式的集合;
3.6关于id问题
在MongoDB集合中的每一行记录都会自动生成一个objectid,其组成是:"时间戳+机器码+PID+计数器",这个id的信息是MongoDB数据库自己为用户生成,不需要维护;
3.7数据删除
数据的删除和修改都很麻烦;
范例:删除数据db.dept.remove({"id":ObjectId("32434deeggsfdgrgc7898")});
后面会讲解其他的删除方法
3.8数据修改
数据修改的意义不大
var deptDate = {
"deptno":50,
"dname":"乞讨",
"loc":"家里",
"count":60,
"avg":9000.0
};
db.dept.update({"id":ObjectId("32434deeggsfdgrgc7898")},deptDate);
3.9删除集合
语法:db.集合名称.drop()
范例:db.dept.drop();
查看show collections;
3.10删除数据库(删除当前所在的数据库)
必须先切换到某个数据库之后才能删除这个数据库
db.dropDatabse()
查看show dbs;
4.数据操作(重点)
数据库的核心操作CRUD
对应MongoDB除了增加数据比较简单,其他的操作都很麻烦,修改是最麻烦的;
4.1数据增加
语法:db.集合.insert()

范例:
use mldn;
db.infos.insert({"url":"www.mldn.cn"});
db.infos.find();
以数组的形式增加
db.infos.insert([
{"url":"www.mldn.cn"},
{"url":"www.mldnjava.cn"}
]
}
);
db.infos.find();
要保存多个数据就使用数组的形式进行保存
范例保存10000条数据,这时使用JavaScript实现
直接执行下面命令即可;
for (var x = 0 ; x < 10000 ; x++){
db.infos.insert({"url" : "mldn -" + x});
}
查询db.infos.find();这里可以通过输入it翻页;如果数据保存很多的情况下,列表时不会全部列出,只会列出部分内容,可以通过it翻页查看更多数据;
4.2数据查询
mongodb中数据查询比较方便,有关系运算、逻辑运算、数组运算、正则运算等。
查询操作核心语法:"db.集合名称.find({查询条件}[,{设置显示的字段}])"
范例:最简单的用法就是直接使用find()函数完成查询
db.infos.find()
范例:查询出url为"www.mldn.cn"的数据
db.infos.find({"url":"www.mldn.cn"});
在数据查询的时候也是按照json格式设置相等关系;
对于设置的显示字段严格来讲就称为数据的投影操作;例如我查询一个数据时可以只显示其中一部分,只把部门名称和员工显示出来,员工的收入不显示出来;不需要显示的字段设置为"0" 需要显示的字段设置为"1"
范例:不显示id----db.infos.find({"url":"www.mldn.cn"},{"_id":0});
db.infos.find({"url":"www.mldn.cn"},{"_id":0,"url":1});
上面这种投影操作意义不大,不建议使用
对于数据的查询还可以使用pretty()函数;
范例:db.infos.find({"url":"www.mldn.cn"},{"_id":0,"url":1}).pretty();----这样查询出来的数据就会先对其进行格式化之后再显示,
4.2.1关系查询
在MongoDB中支持的关系操作:大于($gt)、小于($lt)、大于等于($gte)、小于等于($lte)、不等于($ne)、等于(key:value或$qe).
范例:准备数据
db.students.drop();
db.students.insert({"name":"李白","sex":"男","age":19,"score":80,"address":"深圳"});
db.students.insert({"name":"杜甫","sex":"男","age":20,"score":50,"address":"中山"});
db.students.insert({"name":"李清照","sex":"女","age":88,"score":60,"address":"北京"});
db.students.insert({"name":"骆宾王","sex":"女","age":66,"score":30,"address":"上海"});
db.students.insert({"name":"王炯","sex":"男","age":33,"score":50,"address":"珠海"});
db.students.insert({"name":"张三","sex":"男","age":45,"score":70,"address":"驻马店"});
db.students.insert({"name":"李四","sex":"男","age":34,"score":40,"address":"郑州"});
db.students.insert({"name":"王五","sex":"女","age":34,"score":70,"address":"西安"});
db.students.insert({"name":"狗拽","sex":"男","age":65,"score":80,"address":"山西"});
db.students.insert({"name":"小明","sex":"女","age":65,"score":80,"address":"新疆"});
db.students.insert({"name":"小黄","sex":"女","age":54,"score":90,"address":"泰安"});
db.students.insert({"name":"小白","sex":"男","age":52,"score":60,"address":"青岛"});
db.students.insert({"name":"小红","sex":"女","age":51,"score":70,"address":"潍坊"});
范例一:
db.students.find({"name":"张三"}).pretty();
范例二:查询性别是男的
db.students.find({"sex":"男"}).pretty();
范例三:查询年龄大于20的
db.students.find({"age":{"$gt":20}}).pretty();
范例四:查询成绩高于60的
db.students.find({"score":{"$gte":60}}).pretty();
范例五:查询行吗不是王五的信息
db.students.find({"name":{$ne:"王五"}}).pretty();
注意:在一个json结构里面需要定义其他条件的时候依然是json结构;
4.2.2逻辑运算
逻辑运算主要有三种类型:与($and)、或($or)、非($not、$nor)
范例1:查询年龄在19~20的学生信息
db.students.find({"age":{"$gte":19,"$lte":19}}).pretty();
在进行逻辑运算的时候"and"的连接比较容易,只需要利用","分隔即可;
范例2:查询年龄不是19岁
db.students.find({"age":{"$ne":19}}).pretty();
范例3:查询年龄大于19岁或者成绩大于90分的
db.students.find({"or",[
{"age":{"$gt":19}},
{"score":{"$gt":90}}
]}).pretty();
4.2.3非运算
范例4:对案例3进行求反,得到成就小于等于19且成就小于等于90
db.students.find({"nor",[
{"age":{"$gt":19}},
{"score":{"$gt":90}}
]}).pretty();

上面逻辑运算中"与"比较简单,"或"和"非"稍微复杂一些,需要一个数组来设置条件;
4.2.4求模
模的运算使用"$mod"来完成
语法:{$mod:[数字,余数]}
范例1:求对20求模之后与1的,即21,41这些
db.students.find({"age":{"$mod":[20,1]}}).pretty();
利用求模运算可以编写一些数学的计算公式;
4.2.5范围查询---工作中很重要
只要是数据库,都存在"$in"(在范围之中)、"$nin"(不在范围之中)
范例一:查询姓名是"张三""李四""王五"
db.students.find({"name":{"$in":["张三","李四","王五"]}}).pretty();
范例二:查询姓名不是"张三""李四""王五"
db.students.find({"name":{"$nin":["张三","李四","王五"]}}).pretty();
4.2.6数组查询
MongoDB中支持数组保存;
素材准备
db.students.insert({"name":"铁拐李-A","sex":"男","age":19,"score":60,"address":"深圳","course":["语文","数学","英语","政治"]});
db.students.insert({"name":"铁拐李-B","sex":"男","age":20,"score":60,"address":"深圳","course":["语文","数学"]});
db.students.insert({"name":"铁拐李-C","sex":"男","age":21,"score":60,"address":"深圳","course":["语文","数学","英语"]});
db.students.insert({"name":"铁拐李-D","sex":"男","age":22,"score":60,"address":"深圳","course":["语文","数学","英语","政治"]});
db.students.insert({"name":"铁拐李-E","sex":"男","age":23,"score":60,"address":"深圳","course":["英语","政治"]});
db.students.insert({"name":"铁拐李-F","sex":"男","age":24,"score":60,"address":"深圳","course":["语文","政治"]});

查询:db.students.find().pretty();
下面对数组中数据进行判断可以使用如下运算符:
$all,$size,$slice,$elemMatch
范例一:查询同时参加语文和数学----{"$all",["内容1","内容2",...]}
db.students.find({"course":{"$all":["语文","数学"]}}).pretty();
只要是有语文和数学这两门的都会查出来,其他的有没有不管;但是语文和数学少一个都不会显示出来;
案例二:查询学生地址是深圳的
$all可以用在数组上,也可以用在数据的匹配上
db.students.find("address":{"$all":["深圳"]}).pretty();
案例三:查询数组中第二个内容(index=1,索引下标从0开始)为数学的信息;
既然是数组就可以使用索引来进行操作,即"key.index"来定义索引
db.students.find({"course.1":"数学"}).pretty();
范例四:查询只参加两门课程的学习-----$size 计数
db.students.find({"course":{"$size":2}}).pretty();
范例五:查询返回年龄为19所有学生信息中只显示参加的前两门课程------$slice
对查询返回数据内容数量进行控制,例如返回三个数据我只需要显示两个数据
db.students.find({"age":19},{"course":{"$slice":2}}).pretty();
如果年龄为19的学生参加的课程超过2门,那么只显示前两门课程,后面的不显示
范例六:查询返回年龄为19所有学生信息中只显示参加的后两门课程------$slice
db.students.find({"age":19},{"course":{"$slice":-2}}).pretty();
范例七:查询返回年龄为19所有学生信息中只显示参加的中间两门课程,即第二和第三门课程------$slice
db.students.find({"age":19},{"course":{"$slice":[1,2]}}).pretty();-----跳过1个最多显示2个,可以只显示1个
说明:"$slice":[1,2]----第一个数值1表示跳过几个数据,这里为1就是跳过一个数据,从第二个开始显示,显示第二个和第三个

4.2.7嵌套运算------$elemMatch
在MongoDB中每一个几乎数据可以继续保存其他的集合数据,例如有些学生需要保存家长信息;范例:添加数据
db.students.insert({"name":"李白-F","sex":"男","age":24,"score":60,"address":"深圳","course":["语文","政治"],"parents":[{"name":"李白妈妈","age":33,"gender":"女","job":"局长"},{"name":"李白爸爸","age":29,"gender":"男"}]});
查看语句,查看职位为局长的人,且是parents,年龄大于19岁的
db.students.find({"$and":[{"$age":{"$gte":19}},{"parents":{"$elemMatch":{"job":"局长"}}}]}).pretty();

4.2.8判断某个字段是否存在
使用"$exists"可以判断某个字段是否存在,如果设置为true表示存在,如果设置为false表示不存在;
范例:查询具有parents成员的数据
db.students.find({"parents":{"$exists":true}}).pretty();
范例:查询无course成员数据
db.students.find({"course":{"$exists":false}}).pretty();
可以利用这种方法来进行无需信息的过滤
4.2.9条件过滤---$where
范例一:查询年龄大于20的学员
db.students.find({"$where":"this.age>20"}).pretty();
db.students.find({"this.age>20"}).pretty();
上面这种方法是对数据库中每一行数据进行判断,在数据量大的时候不建议使用这种方式
可以使用js函数进行查询
db.students.find(function(){return this.age>20;}).pretty();
db.students.find({"$where":function(){return this.age>20;}}).pretty();
上面是只有一个判断条件,如果有多个判断条件可使用and连接
例如查询年龄在19到21之间的,这样查询出来的只有20
db.students.find({"$and":[{"$where":"this.age>19"},{"$where":"this.age<21"}]}).pretty();
虽然这种形式的操作可以实现数据查询,但是最大缺点是将MongoDB里面保存的BSON数据变为了JavaScript的语法结构,这样的方式不方便使用数据库索引机制。
4.2.10正则运算
如果想实现模糊查询,则必须使用正则表达式,而且正则表达式使用的是语言Perl兼容的正则表达式形式,使用正则表达式方法如下:
基础语法:{key:正则标记};
完整语法:{key:{"$regex":正则标记,"$options":选项}}
options在设置正则信息查询时标记如下:
i:忽略字母大小写
m:多行查找
x:空白字符串出了呗转义的或在字符类中意外的完全忽略
s:匹配所有字符,包括换行内容;
注意点:如果直接使用(JavaScript)则只能使用i和m
而"x"和"s"必须使用"$regex"
范例:查询以"铁"开头的学员信息
db.students.find({"name":/铁/}).pretty();-----这里的铁不可加引号,加上引号就是字符串了
范例二:查询名字中含有字母A的
db.students.find({"name":/a/i}).pretty();-----这里的i就是不区分大小写
说明:如果只需要执行模糊查询操作,严格讲只需要像上面这样编写一个关键字就可以了;
完整格式写法:
db.students.find({"name":{"$regex":/a/i}}).pretty();
正则操作之中除了可以查询出单个字段内容之外,还可以进行数组的查询。
范例:查询course中带有"语"的内容
db.students.find({"course":{"$regex":/语/}}).pretty();
MongoDB中的正则符合和之前使用的JavaScript等正则有一些差别,这里只用在模糊查询就好了,最好不要用更多的正则表达式;

 

posted @ 2018-09-07 16:59  五柳峰  阅读(321)  评论(0编辑  收藏  举报