mongodb是最近几年最火的nosql数据库,在很多大型企业应用广泛,今天就一起学习它的用法。花了一周时间,整理下面的学习记录,希望对大家有所帮助。
mongodb
1. mongodb的安装,
windows 10可以安装,一般作为服务都是安装在Linux服务器上。
具体安装方法有很多,我用的是Ubuntu16 ,直接在官网下载的deb安装文件,总共有四个文件,可以根据需要选择安装。
mongodb-org-mongos_4.2.8_amd64.deb
包含mongos ,用于集群服务
mongodb-org-server_4.2.8_amd64.deb
包含mongod ,服务程序
mongodb-org-shell_4.2.8_amd64.deb
包含mongo命令,cli控制台
mongodb-org-tools_4.2.8_amd64.deb
包含了多个命令,主要是数据的导入导出工具,和gridfs工具
mongodump
mongoexport
mongofiles
mongoimport
mongorestore
mongostat
mongotop
2.认证操作
mongodb默认是没有密码的,这是很不安全的,前两年出现的数据泄露事件就是数据库裸奔导致的,所以部署到线上的应用一定要保证数据库的安全。
MongoDB采用基于角色的访问控制(RBAC)来确定用户的访问,系统提供了很多角色,可以直接使用
角色表
增加用户
db.createUser(
{
user: "root",
pwd: "root",
roles: [ "readWrite"]
}
);
指定db
db.createUser(
{
user: "root",
pwd: "root",
roles: [ {role:"readWrite", db:"shop"} ]
}
);
用户认证
db.auth("admin", "123123")
返回1为认证成功
3.基本操作
作为数据库,最基本的操作就是增删改查(curd)
使用shop库,建一张表goods,存放商品信息,演示如何操作:
a.新增商品
数据库和数据表都不需要事先创建,在用的时候会自动创建,所以写的时候千万不要写错,否则错了也不会报错。
use shop
db.goods.insert({
"name":"电脑",
"brand":"dell",
"style":"s120",
"price":5000,
"size":["small", "mid", "big"],
"desc":{
"cpu":"i7",
"mem":16,
"disk":500
},
"address":"china",
"os":"windows 10"
})
db.goods.insert({
"name":"电脑",
"brand":"lenovo",
"style":"s100",
"price":3000,
"size":["small", "mid", "big"],
"desc":{
"cpu":"i5",
"mem":16,
"disk":250
},
"address":"china",
"os":"windows 10"
})
b.查询数据
db.goods.find() 或db.goods.find({}),可以查出所有记录
查询价格5000的记录
db.goods.find({"price": 5000})
查询数组中包含'mid'的记录
db.goods.find({"size": 'mid'})
查询数组第一个元素是'small'的记录
db.goods.find({"size.0": 'small'})
查询内嵌对象,查询cpu是i7的记录
db.goods.find({"desc.cpu": 'i7'})
查询不存在某字段的记录,如没有价格字段的记录
db.goods.find({"price":null})
查询还有更多更丰富的查询方法。
c.修改数据
增加或字段值,使用$set ,否则第二个参数没写的字段会丢失。
db.goods.update({"_id" : ObjectId("5fe7dd7e6b7131b2943cd24f")},{"$set":{"price":100}})
d.删除数据
删除所有,remove必须有一个参数,这点和find不同。
db.goods.remove({})
删除name是aaa的记录
db.goods.remove({"name":"aaa"})
4.高级操作
复杂查询
逻辑与and ,相当于操作符&&,每个条件都要满足
如查询品牌为dell且价格为5000的记录
db.goods.find({"$and":[{"brand":"dell"}, {"price":"5000"}]})
数组中可以增加更多的条件。
逻辑或or ,相当于操作符||,只需要满足一个
如查询品牌为dell或价格为5000的记录,只要前面的条件满足,后面的就不会再验证
db.goods.find({"$or":[{"brand":"dell"}, {"price":"5000"}]})
聚合操作
为了演示聚合函数功能,我们增加一个新的集合,score,存储学生成绩,
db.score.insert({
"user_id":4,
"class_id":1,
"subject":"语文",
"score":95
})
在关系型数据库中,聚合操作是很常见的操作,在mongodb中,也很容易实现,聚合操作用aggregate方法:
参数是一个数组,
db.score.aggregate([
{"$group":{"_id":"class_id", "total":{"$sum":"$score"}}}
])
说明:
$group,分组,_id表示分组字段是class_id,
total是结果显示名,可随意定义,
"$sum":"$score" ,sum是求和,$+字段表示聚合操作的字段。
除了sum求和,其他常见的还有:
max ,求最大值
min,求最小值
avg,求平均值
first, 求第一个
last,求最后一个
> db.score.find()
{ "_id" : ObjectId("5fe92f3120f4a8961249507b"), "user_id" : 1, "class_id" : 1, "subject" : "语文", "score" : 100 }
{ "_id" : ObjectId("5fe92f5420f4a8961249507c"), "user_id" : 2, "class_id" : 1, "subject" : "语文", "score" : 90 }
{ "_id" : ObjectId("5fe92f6e20f4a8961249507d"), "user_id" : 3, "class_id" : 1, "subject" : "语文", "score" : 88 }
{ "_id" : ObjectId("5fe92f7d20f4a8961249507e"), "user_id" : 4, "class_id" : 1, "subject" : "语文", "score" : 95 }
特殊一些的push、addToSet
把字段的值放入一个数组中,如下:
> db.score.aggregate([ {"$group":{"_id":"class_id", "total2":{"$push":"$score"}}} ])
{ "_id" : "class_id", "total2" : [ 100, 90, 88, 95 ] }
如果我们要先查出需要的数据,然后再进行聚合,就像我们写sql,先用where过滤,然后再group,
这时候就需要用到match关键词了,实例如下:
db.score.aggregate([
{"$match":{"class_id":2}},
{"$group":{"_id":"class_id", "total2":{"$push":"$score"}}}
])
连表操作
在MySQL,经常用到多表查询,如要查询每个同学各科总分,就需要学生表和分数表,在mongodb也可以通过连表实现。
学生表
> db.student.find()
{ "_id" : ObjectId("5fe9413a20f4a89612495087"), "id" : 1, "name" : "vincent", "age" : 18, "class_id" : 1 }
...
分数表
> db.score.find()
{ "_id" : ObjectId("5fe92f3120f4a8961249507b"), "user_id" : 1, "class_id" : 1, "subject" : "语文", "score" : 100 }
如果统计id=4的同学的成绩,需要如下的方法:
db.student.aggregate(
[
{"$match":{"id":4}},
{"$lookup":{
"from": "score",
"localField": "id",
"foreignField": "user_id",
"as": "scores"
}}
]
)
说明:
localField是主集合(student)的字段,foreignField是关联集合(score)中的字段,as是以数组返回的关联集合数据。
查询结果如下:
{
"_id" : ObjectId("5fe9417020f4a8961249508a"),
"id" : 4,
"name" : "lily",
"age" : 15,
"class_id" : 1,
"scores" : [
{
"_id" : ObjectId("5fe92f7d20f4a8961249507e"),
"user_id" : 4,
"class_id" : 1,
"subject" : "语文",
"score" : 95
},
{
"_id" : ObjectId("5fe9409520f4a89612495082"),
"user_id" : 4,
"class_id" : 1,
"subject" : "数学",
"score" : 89
},
{
"_id" : ObjectId("5fe940e320f4a89612495083"),
"user_id" : 4,
"class_id" : 1,
"subject" : "英语",
"score" : 77
}
]
}
....
unwind可以将scores数组拆分开,分成多条记录
db.student.aggregate(
[
{"$match":{"id":4}},
{"$lookup":{
"from": "score",
"localField": "id",
"foreignField": "user_id",
"as": "scores"
}},
{
"$unwind":"$scores"
}
]
)
结果将变成四条记录
{
"_id" : ObjectId("5fe9417020f4a8961249508a"),
"id" : 4,
"name" : "lily",
"age" : 15,
"class_id" : 1,
"scores" : {
"_id" : ObjectId("5fe92f7d20f4a8961249507e"),
"user_id" : 4,
"class_id" : 1,
"subject" : "语文",
"score" : 95
}
}
{
"_id" : ObjectId("5fe9417020f4a8961249508a"),
"id" : 4,
"name" : "lily",
"age" : 15,
"class_id" : 1,
"scores" : {
"_id" : ObjectId("5fe9409520f4a89612495082"),
"user_id" : 4,
"class_id" : 1,
"subject" : "数学",
"score" : 89
}
}
{
"_id" : ObjectId("5fe9417020f4a8961249508a"),
"id" : 4,
"name" : "lily",
"age" : 15,
"class_id" : 1,
"scores" : {
"_id" : ObjectId("5fe940e320f4a89612495083"),
"user_id" : 4,
"class_id" : 1,
"subject" : "英语",
"score" : 77
}
}
除了上面几个操作符,常用的还有project、sort、limit等,充分利用这些操作符,能实现很多复杂的功能。
最后,介绍一个mongodb的图形界面管理工具robo 3T,这不是本篇介绍的重点
下载地址
https://robomongo.org/download ,在这个站点,还有另一个工具studio 3t,是商业软件,是收费的,不缺银子的可以使用。
robo 3t,是一个非常好用的工具,对于新入手的同学,可以拿来用一下。官方提供两个版本,exe和zip,安装版和解压版。