MongoDB的基本操作

一·mongodb的基本操作

1.数据库使用

  • 开启 mongodb 服务:要管理数据库,必须先开启服务,开启服务使用 mongod --dbpath

c:\mongodb

  • 管理 mongodb 数据库:mongo (一定要在新的 cmd 中输入)

  • 查看所有数据库列表 :show dbs

2.创建数据库

  • 使用数据库,创建数据库:use student

  • 如果真的想把这个数据库创建成功,那么必须插入一个数据。

    数据库中不能直接插入数据,只能往集合(collections)中插入数据。不需要专门创建集合,只需要写点语法插入数据就会创建集合:

    db.student.insert({“name”:”xiaoming”});

    db.student 系统发现 student 是一个陌生的集合名字,所以就自动创建了集合。

  • 显示当前的数据集合(mysql中叫表)

    show collections
  • 删除数据库,删除当前所在的数据库

    db.dropDatabase();
  • 删除集合,删除指定的集合 (删除表)

    db.user.drop()

    ##

3.插入(添加)数据

  • 插入数据,随着数据的插入,数据库创建成功了,集合也创建成功了

    db.表名.insert({"name":"zhangsan"}); student 集合名称(表)

     

4.查找数据

4.1查找所有记录

db.user.find()
相当于:select*from user

4.2查询去掉后的当前聚集集合中的某列的重复数据

db.user.distinct('name');
会过滤掉name中的相同数据
相当于select distict name from user

4.3查询age=22的记录

db.user.find({'age':22})
相当于:select * from user where age = 22

4.4查询age>22的记录

db.user.find({'age':{$gt:22}})//大于号用$gt
相当于select * from user where age > 22

4.5查询age<22的记录

de.user.find({age:{$lt:22}}) //小于号用$lt
相当于:select * from user where age < 22

4.6查询age>=22的记录

db.user.find({age:{$gte:22}}) //大于等于 $gte
相当于:select * from user where age >= 22

4.7查询age<=25的记录

db.user.find(age:{$lte:22}) //小于等于 $lte
相当于:select * from user where age <= 22

4.8查询age >= 23 并且 age <=26

db.user.find({age:{$gte:23,$lte:26}})
相当于:select * from user where age >= 23 and age <=26

4.9 模糊查询用于搜索

//查询 name中包含 mongo 的数据
db.user.find(name:/mongo/)
//相当于%%
select * from userInfo where name like '%mongo%'

//查询 name 中以 mongo 开头的
db.user.find(name:'/^mongo/')
相当于select * from user where name like 'mongo%'

4.10查询指定列name,age数据

db.user.find({},{name:1,age:1})
相当于:select name,age from user
第一个花括号是查询过滤的条件
第二个花括号是查询值的字段数据,这里指定了name和age查询出来的结果只包含name和age的信息
当然 name 也可以用 true 或 false,当用 ture 的情况下和 name:1 效果一样,如果用 false 就是排除 name,显示 name 以外的列信息。

4.11查询指定列name,age数据age>25

db.user.find({age:{$gt:25}},{name:1,age:1})
相当于:selcet name,age from user where age > 25

4.12按照年龄排序 1升序 -1降序

升序:db.user.find().sort({age:1})
降序:db.user.find().sort({age:-1})

4.13查询name=zhangsan,age=12的数据

db.user.find({name:'zhangsan',age:22})
相当于select * from user where name = 'zhangsan' and age = '22'

4.14查询5条数据

db.user.find().limit(5) //limit(5)限制使用5条
相当于 select top 5 from user

4.15查询10条以后的数据

db.user.find().skip(10) //skip(10)跳过十条数据
相当于select * from user where id not in(select top 10 * from user)

4.16查询在5~10之间的数据

db.user.find().limit(10).skip(5)
可用于分页,limit是pageSize一页显示多少条,skip:跳过多少条数据
分页公式:当前页 - 1 * 跳过的数据 

4.17or与查询

db.user.find({$or:[{age:22},{age:25}]})
相当于:select * from user where age= 22 or age = 25

4.18查询一条数据

db.user.findOne()
相当于:select top 1 from user
db.user.find().limit(1);

4.19查询某个结果集的记录条数 统计数量

db.user.find({age:{$gte:25}}).count()
相当于select count(*) from user where age >= 25
注意:
如果要返回限制之后的巨鹿数量,要使用count(true)或者count(非0)
db.user.find().skip(10).limit(5).count(true)

5.修改数据

1.修改要有查询条件,要改什么内容如,要告诉mongo
	查找名字叫做小明的,把年龄更改为16
	db.student.update({'name':小明},{$set:{'age':16}})
	查找数学成绩为70的学生,把年龄更改为33
	db.student.update({'score,shuxue':70},{$set:{'age:':33}})
	//第一个花括号是查询的条件,第二个花括号是修改的内容
	修改多条数据
	1 db.student.update({"sex":"男"},{$set:{"age":33}},{multi: true});
	//{multi:true}表示更新多条
	
	注意:
	如果不加$set会将此条数据替换成要修改的内容
	db.student.update({"name":"小明"},{"name":"大明","age":16});
	
	//其他用法
	db.user.update({name:'lisi'},{$inc:{age:50}},false,true)
	相当于
	unpdate users set age = age + 50 where name = 'lisi'
	
	
	db.users.update({name:'lisi'},{$inc:{age:50},$set:{name:'zhangsan'}},false,true)
	相当于:update users set age = age + 50,name = 'zhangsan' where name = 'lisi'

6.删除数据

db.collectionsName.remove({删除的条件})
例:
db.users.remove({name:'zhangsan'})//删除users集合中名字等于zhangsan的这条数据

//删除一条添加justOne:true
db.users.remove({'age':18},{justOne:true})

二.mongodb索引和explain的使用

1.索引基础

索引是对数据库表中一列或多列的值进行排序的一种结构,可以让我们查询数据库变得

更快。MongoDB 的索引几乎与传统的关系型数据库一模一样,这其中也包括一些基本的查

询优化技巧。

//创建索引
db.user.ensureIndex({'name':1})
//获取当前集合的索引
db.user.getIndexes()
//删除索引
db.user.dropIndex({'name':1})

2.在 MongoDB 中,我们同样可以创建复合索引

如:数字 1 表示 username 键的索引按升序存储,-1 表示 age 键的索引按照降序方式存储。

db.user.ensureIndex({'name':1,'age':-1})

该索引被创建后,基于 username 和 age 的查询将会用到该索引,或者是基于 username

的查询也会用到该索引,但是只是基于 age 的查询将不会用到该复合索引。因此可以说,

如果想用到复合索引,必须在查询条件中包含复合索引中的前 N 个索引列。然而如果查询

条件中的键值顺序和复合索引中的创建顺序不一致的话,MongoDB 可以智能的帮助我们调

整该顺序,以便使复合索引可以为查询所用。如:

db.user.find({'age:30','name':'zhangsan'})

3.唯一索引

//创建唯一索引
db.user.ensureIndex({'userID':1},{'inique':true})

如果插入的文档中不包含 userid 键,那么该文档中该键的值为 null,如果多次插入类似
的文档,MongoDB 将会报出同样的错误,如:
db.user.insert({userId1:5})
db.user.insert({userId1:5})

//删除唯一索引
db.user.dropIndex({'userId':1})

我们同样可以创建复合唯一索引,即保证复合键值唯一即可。如:
db.user.ensureIndex({"userid":1,"age":1},{"unique":true})

4.索引的参数

ParameterTypeDescription
background Boolean 建索引过程会阻塞其它数摆库操作. background可指定以后台方式创建素引.即增加"background" 可选参数。 background"默认值为false.
unique Boolean 建立的索引是否唯一。指定为true创建唯一 索引。 默认值为false.
name string 素引的名称。如果未指定. MongoDB的通过连接素引的字段名和排序顺序生成-个素引名称。
dropDups Boolean 在建立唯一索引时是否删除里复记录指定true创建唯一索引。 默认值为false.

如果在为已有数据的文档创建索引时,可以执行下面的命令,以使 MongoDB 在后台创

建索引,这样的创建时就不会阻塞其他操作。但是相比而言,以阻塞方式创建索引,会使整

个创建过程效率更高,但是在创建时 MongoDB 将无法接收其他的操作。

db.user.ensureIndex({"username":1},{"background":true})

5.explain的使用

explain executionStats 查询具体的执行时间

db.users.find().explain('executionStats')

三.MongoDB账户权限配置

1.第一步配置超级管理用户

use admin

db.createUser({
user:'admin',
pwd:'123456',
roles:[{role:'root',db:'admin'}]
})

//查看用户
show users
//创建用户
db.createUser({
user:'admin',
pwd:'123456',
roles:[{role:'root',db:'addmin'}]
})
//删除用户
db.dropUser('admin')//括号内是要删除用户的数据库名称
//修改用户密码
db.updateUser('admin',{pwd:'admin'})//第一个参数是要修改那个数据库
//权限认证
db.auth('admin','123456')//第一个参数是要连接的数据库,第二个参数是密码


Mongodb数据库角色
1.数据库用户角色,read. readWrite;
2.数据库管理角色,dbAdmin、 dbOwner、 userAdmin
3.集群管理角色,clusterAdmin、 slusterManager. clusterMonitor、 hostManager:
4.备份恢复角色,backup、 restore
5.所有数据库角色: readAnyDatabase、 readWriteAnyDatabe、 userAdminAnyDatabase 、dbAdminAnyDatabase
6.超级用户角色: root

2.第二步修改MongoDB数据库配置文件

C:\Program Files\MongoDB\Server\4.1\bin\mongod.cfg
配置
security:
	authorization:enabled//开启权限验证

3.重启MongoDB服务

 

4.第四部用超级管理员账户连接数据库

mongo admin -u 用户名 -p 密码
mongo 139.199.85.20/admin -u 用户名 -p 密码 //远程连接

5.第五步给其他数据库建立单独的用户

use blog

db.createUser({
	user:'blog',
	pwd:'123456',
	roles:[{role:'dbOwner',db:'blog'}]
})

四.MongoDB 的高级查询 aggregate 聚合管道

MongoDB 中使用 db.COLLECTION_NAME.aggregate([{},...]) 方法 来构建和使用聚合管道。先看下官网给的实例,感受一下聚合管道的用法。

 

1.MongoDB Aggregation 管道操作符与表达式

管道操作符description备注
$project 增加,删除,重命名字段 修改文档的结构,可以用来重命名、增加或删除文档中的字段
$match 条件匹配,只满足条件的文档才能进入下一阶段 用于过滤文档。用法类似于 find() 方法中的参数。
$limit 限制结果的数量 可以用于分页
$skip 跳过文档的数量 可以用于分页
$sort 条件排序。 默认为升序,1为升序, -1为降序
$group 条件组合结果 统计  
$lookup $lookup 操作符 用以引入其它集合的数  

2.SQL和nosql对比

 

sqlnosql
where $match
GROUP BY $group
HAVING $match
SELECT $project
ORDER BY $sort
LIMIT $limit
SUM() $sum
COUNT() $count
join $lookup

3.管道表达式

  • 管道表达式作为'键',所对应的'值'叫做管道表达式

  • 列如{$match:{age:{$gte:18}}}其中$match称为管道操作符,而age:{$gte:18}称为管道表达式

  • 每一个管道表达式是一个文档结构,它是由字段名,字段值,和一些表达式操作符组成的

     

常用表达式操作符Description
$addToSet 将文档指定字段的值去重
$max 文档指定字段的最大值
$min 文档指定字段的最小值
$sum 文档指定字段求和
$avg 文档指定字段求平均值
$gt 大于给定的值
$lt 小于给定的值
$eq 等于给定的值
$gte/$lte 大于等于/小于等于

4.模拟数据

db.order.insert({"order_id":"1","uid":10,"trade_no":"111","all_price":100,"all_num":2}) 

db.order.insert({"order_id":"2","uid":7,"trade_no":"222","all_price":90,"all_num":2}) 

db.order.insert({"order_id":"3","uid":9,"trade_no":"333","all_price":20,"all_num":6}) 

db.order_item.insert({"order_id":"1","title":"商品鼠标 1","price":50,num:1}) 

db.order_item.insert({"order_id":"1","title":"商品键盘 2","price":50,num:1}) 

db.order_item.insert({"order_id":"1","title":"商品键盘 3","price":0,num:1}) 

db.order_item.insert({"order_id":"2","title":"牛奶","price":50,num:1}) 

db.order_item.insert({"order_id":"2","title":"酸奶","price":40,num:1}) 

db.order_item.insert({"order_id":"3","title":"矿泉水","price":2,num:5}) 

db.order_item.insert({"order_id":"3","title":"毛巾","price":10,num:1})

1.$project的使用

  • 修改文档的结构,可以用来重命名、增加或删除文档中的字段。

  • 指定返回数据所包含的字段

要求查找 order 只返回文档中 trade_no 和 all_price 字段
db.order.aggregate([
	{
		$project:{trade_no:1,all_price:1}
	}
])
相当于
db.user.find({},{trade_no:1,all_price:1})
相当于:select name,age from user
第一个花括号是查询过滤的条件
第二个花括号是查询值的字段数据,这里指定了trade_no和all_price查询出来的结果只包含trade_no和all_price的信息
当然 trade_no 也可以用 true 或 false,当用 ture 的情况下和 trade_no:1 效果一样,如果用 false 就是排除 trade_no,显示trade_no 以外的列信息。

2.$match

  • 用于过滤文档。用法类似于 find() 方法中的参数。

    要求查找 order 只返回文档中 trade_no 和 all_price 字段,并且all_price大于等于90的数据
    db.order.aggregate([
    {
    	$project:{trade_no:1,all_price:1}
    },
    {
    	$match:{'all_price':{$gte:90}}
    }
    ])
    //查询结果
    { "_id" : ObjectId("5e9ac7b34e4fafbdc97a2ff8"), "trade_no" : "111", "all_price" : 100 }
    { "_id" : ObjectId("5e9ac7c74e4fafbdc97a2ff9"), "trade_no" : "222", "all_price" : 90 }
    相当于
    db.order.find({'all_price':{$gte:90}},{trade_no:1,all_price:1})
    
    select trade_no,all_price from order where all_price >= 90

     

3.$group

  • 将集合中的文档进行分组,可用于统计结果。

    统计每个订单的订单数量,按照订单号分组

    db.order_item.aggregate([
    	{
    		$group:{_id:'$order_id,total:'{$sum:'$num'}}
    	}
    ])
    //查询结果
    { "_id" : "3", "total" : 12 }
    { "_id" : "2", "total" : 100 }
    { "_id" : "1", "total" : 100 }
    相当于
    select sum(num) from order_item group by order_id
    

     

4.$sort将集合中的文档进行排序。

//查询只包含trade_no,all_price字段,并且all_price大于90,以all_price降序排序
db.order.aggregate([
    {
    	$project:{trade_no:1,all_price:1}//只包含trade_no,all_price字段
    },
    {
    $match:{'all_price':{$gte:90}}//all_price大于等于90
    },
    {
    $sort:{'all-price':-1}//以all_price降序排序
    }
])
//查询结果
{ "_id" : ObjectId("5e9ac7b34e4fafbdc97a2ff8"), "trade_no" : "111", "all_price" : 100 }
{ "_id" : ObjectId("5e9ac7c74e4fafbdc97a2ff9"), "trade_no" : "222", "all_price" : 90 }
相当于
select tradde_no,all_price from order where all_price >= 90 order by all_price desc

 

5.$limit限制返回的数量

db.order.aggregate([
	{
		$project:{trade_no:1,all_price:1}
	},
	{
	$match:{'all_price':{$gte:90}}
	},
	{
	$limit:1
	}
])
//查詢结果
{ "_id" : ObjectId("5e9ac7b34e4fafbdc97a2ff8"), "trade_no" : "111", "all_price" : 100 }
相当于
db.order.find({'all_price':{$gte:90}},{trade_no:1,all_price:1}).limit(1)

select top 1 trade_no,all_price from order where all_price >= 90

6.$skip跳过的数量

db.order.aggregate([
	{
		$project:{trade_no:1,all_price:1}
	},
	{
		$match:{'all_price':{$gte:90}}
	},
	{
		$sort:{'all_price':-1}
	},
	{
		$skip:1
	}
])
//查询你结果
{ "_id" : ObjectId("5e9ac7c74e4fafbdc97a2ff9"), "trade_no" : "222", "all_price" : 90 }
//相当于
select trade_no,all_price from order where all_price >= 90 and  _id not in (select top 1 from order)

db.order.find({'all_price':{$gte:90}},{trade_no:1,all_price:1}).sort({'all_price':-1}).skip(1)
//查询结果是一样的
{ "_id" : ObjectId("5e9ac7c74e4fafbdc97a2ff9"), "trade_no" : "222", "all_price" : 90 }

7.$lookup 表关联

db.order.aggregate([
    {
    	$lookup:
    	{
			from:'order_item',//要关联的表
			localField:'order_id',//要关联的字段
			foreignField:'order_id',//关联表的id
			as:'items'//存储在那个字段里
		}
    }
	
])


//查询结果
{
	"_id": ObjectId("5e9ac7b34e4fafbdc97a2ff8"),
	"order_id": "1",
	"uid": 10,
	"trade_no": "111",
	"all_price": 100,
	"all_num": 2,
	"item": [{
		"_id": ObjectId("5e9ac7d14e4fafbdc97a2ffb"),
		"order_id": "1",
		"title": "商品鼠标 1",
		"price": 50,
		"num": 1
	}, {
		"_id": ObjectId("5e9ac7d64e4fafbdc97a2ffc"),
		"order_id": "1",
		"title": "商品键盘 2",
		"price": 50,
		"num": 1
	}, {
		"_id": ObjectId("5e9ac7db4e4fafbdc97a2ffd"),
		"order_id": "1",
		"title": "商品键盘 3",
		"price": 0,
		"num": 1
	}]
} {
	"_id": ObjectId("5e9ac7c74e4fafbdc97a2ff9"),
	"order_id": "2",
	"uid": 7,
	"trade_no": "222",
	"all_price": 90,
	"all_num": 2,
	"item": [{
		"_id": ObjectId("5e9ac8024e4fafbdc97a2ffe"),
		"order_id": "2",
		"title": "牛奶",
		"price": 40,
		"num": 1
	}, {
		"_id": ObjectId("5e9ac8074e4fafbdc97a2fff"),
		"order_id": "2",
		"title": "牛奶",
		"price": 50,
		"num": 1
	}]
} {
	"_id": ObjectId("5e9ac7cb4e4fafbdc97a2ffa"),
	"order_id": "3",
	"uid": 9,
	"trade_no": "333",
	"all_price": 20,
	"all_num": 6,
	"item": [{
		"_id": ObjectId("5e9ac80a4e4fafbdc97a3000"),
		"order_id": "3",
		"title": "矿泉水",
		"price": 2,
		"num": 5
	}, {
		"_id": ObjectId("5e9ac80e4e4fafbdc97a3001"),
		"order_id": "3",
		"title": "毛巾",
		"price": 10,
		"num": 1
	}]
}

 

posted @ 2020-06-20 15:25  萝卜青菜各有所爱  阅读(446)  评论(0)    收藏  举报