mongo速记一
一. 概述
就和描述里提到的一样,这次依旧是简单使用.crud以及聚合(管道)简单介绍.而且是基于单实例.写这个主要还是留作备份,以免以后长时间不用忘记了,到时候完整的看官方文档比较耗时间.所以这篇blog更多的是说明以及使用的一个例子.更多的option或者command不会列出,实际使用时可查寻官方文档~
当然这里的所有内容都可以在官网文档中找到~
二.素材准备
可以到官网下载server以及mongo shell
三.安装以及数据库准备
我这边是debian,所以下载的是deb文件直接dpkg -i
就可以了.
然后就是启动以及配置问题.很多选项都可以通过命令行的形式指定,但是这边还是建议通过配置文件来实现.默认的配置文件位于/etc/mongo.conf.这边可以复制出来修改使用.
首先是storage也是是数据存储部分.debian下默认是在 /var/lib/mongodb,自然可以根据自己的需求来配置,修改下图的dbPath即可
storage:
dbPath: /var/lib/mongodb
systemLog部分则是日志存储位置,同样依照自己的需求修改即可
systemLog:
destination: file
logAppend: true
path: /var/log/mongodb/mongod.log
然后是通信的端口以及监听IP.这个和socket一样,可以选择本地还是内网还是公网.
net:
port: 27017
bindIp: 127.0.0.1
这是他的默认配置也就是说仅仅支持本地访问.如果需要的可以在后面继续添加,比如增加局域网访问
bindIp: 127.0.0.1,192.168.111.111
当然你也可以选择0.0.0.0 直接监听所有网络请求.
security:
authorization:enabled
这个则是开启用户认证的模块.(还有很多内容参见官网,比如fork,oplogSize等)
不过在开启之前需要新建一个用户,并且设置为admin用户,不然这个用户鉴权部分也就没有意义了.
新建用户:
db.createUser({user:"myAdmin",pwd:"xxxx",roles:[{role:"userAdminAnyDatabase",db:"admin"},{role:"dbAdmin",db:"admin"},{role:"clusterAdmin",db:"admin"}]})
这里简单说明下,userAdminAnyDatabase 则是赋予myAdmin用户所有db的用户管理权限,dbAdmin自然是管理自己的admin,clusterAdmin 则是集群的.这边如果遇到db.auth 认证日志出现两次结果,一次成功,一次replSet认证失败可以添加这个权限以继续下面的操作.
还有就是admin用户仅仅是管理功能,并不包含read 和 write 权限.
当然权限还有很多,具体的可以参考这个链接的文章.
现在创建一个新的测试库,use 一个不存在的库他会自动创建
use testdb
这时候其实在show dbs
的时候 testdb是不可见的,只有在插入数据的时候才可见.
新建testdb的管理员:
db.createUser({user:"testdbAdmin",pwd:"xxxx",roles:[{role:"dbAdmin",db:"testdb"},{role:"dbOwner",db:"testdb"}]})
用户创建成功后就可以退出重新用testdb用户登录了:
use testdb
db.auth({user:"testdbAdmin",pwd:"xxxx"})
如果返回1
就是认证成功了.
创建一个测试集合testC并插入第一条数据(同样不存在自动创建):
db.testC.insert({name:"first"})
如果返回WriteResult({"nInserted":1})则说明插入成功了,这时候如果在另外一个mongo shell中myAdmin用户登录,查看所有数据库show dbs
会发现testdb 已经可以正常显示了.
四.CRUD
插入:
db.collectionName.insert()
db.collectionName.insertOne({xxx:xxx})
db.collectionName.insertMany([{xxx:xxx},{xxx:xxx}])
db.testC.insertOne({name:"first"})
db.testC.insertMany([{name:"first"},{name:"second"},{name:"third"},{name:"toDelete"}])
如果没有指定_id字段,mongo则会自动生成该字段作为索引.(对于批量操作还有有序和无序之分,具体参见官方文档)
查询:
db.collectionName.find(<filter>,<projection>)
filter 是查询条件,projections是投影,其实是对数据做一些限制
// select * from testC
db.testC.find()
// select name from testC where name >= "third" or _id = ObjectId("5ce91317811bea15014713f5");
db.testC.find({$or:[{name:{$gte:"third"}},{_id:ObjectId("5ce91317811bea15014713f5")}]},{_id:0})
这条语句的大体意思和注释类似,其中_id:0 的意思是_id 字段不返回,其余类似or的还有and,类似gte的还有gt,lte,lt,ne,in
等.
结果如下:
{
"name" : "first"
}
{
"name" : "third"
}
{
"name" : "todrop"
}
删除:
db.collectionName.deleteOne()
db.collectionName.deleteMany()
db.colletcionName.drop()
drop则是删除对应集合中的所有文档.
// delete from testC where name = "todrop"
db.testC.deleteOne({name:"todrop"})
更新
// db.collection.update( criteria, objNew, upsert, multi )
db.collectionName.updateOne(<filter>, <update>, <options>)
db.collectionName.updateMany(<filter>, <update>, <options>)
db.collectionName.replaceOne(<filter>, <update>, <options>)
// update testC set name = "1" where name = first
// updateOne 则是只更新一条.老版本是有update方法的,会有option true or false 指定更新一条还是多条 就是multi这个字段,upsert 则是指定未查询到时是否创建
db.testC.updateMany({name:"first"},{$set:{name:"1"}})
五.聚合
这个有点类似管道就是数据一轮一轮的处理
db.collectionName.aggregate(AGGREGATE_OPERATION)
这个这里也仅仅是提示下有这种用法,这是一个示例
db.collectionName.aggregate([
{
// filter1
$match:{
"_id":{$gte:ObjectId("xxx"),$lt:ObjectId("xxx")}
}
},
{
//filter2
$match:{
"field1":{$in:[
'111',
'222',
'333',
'444'
]
},
"field2":filedValue2
}
},
{
//aggregate
$group:{
_id:"$columnName",
count:{$sum:1},
alias1:{$sum:"$field3"},
alias2:{$sum:"$field4"}
}
}
])
这里简单说明下:这段语句的意思就是首先经过filter1的数据再经过filter2的过滤(先按照filter1的索引过滤这样第二个filter会快点),后面则是按照columnName字段分组,count:{$sum:1}
则是统计行数作为count,这里$sum如果不指定字段则是统计行数,统计field3的和作为alias1的值,统计field4的和作为alias2的值
举个小例子
数据如下:
db.testC.insertMany(
[
{name:"first",age:1,city:"shanghai",score:90},
{name:"second",age:2,city:"shanghai",score:91},
{name:"third",age:3,city:"shanghai",score:92},
{name:"fourth",age:4,city:"nanjing",score:93},
{name:"fifth",age:5,city:"nanjing",score:94},
{name:"left",age:4,city:"unknow",score:100}
]
)
执行语句如下:其中5ce925cf10bc5eb4a70f8782
是first的_id值
db.testC.aggregate([
{
$match:{
"_id":{$gt:ObjectId("5ce925cf10bc5eb4a70f8782")}
}
},
{
$match:{"city":{$in:[
"shanghai",
"nanjing"
]}}
},
{
$group:{
_id:"$city",
count:{$sum:1},
ageSum:{$sum:"$age"},
scoreSum:{$sum:"$score"}
}
}
])
结果如下:
{
"_id" : "nanjing",
"count" : NumberInt(2),
"ageSum" : 9.0,
"scoreSum" : 187.0
}
{
"_id" : "shanghai",
"count" : NumberInt(2),
"ageSum" : 5.0,
"scoreSum" : 183.0
}
六.补充
这里很多内容没有涉及,例如索引以及事务副本集等.均可以参考官方文档.还有就是可以通过部分可视化工具简化操作例如mongochef等