一、 MongoDB简介
MongoDB:文档数据库,存储的是Bson格式文档(Bson是json的二进制化)。{name:'haha',age:9}
特点::内部执行引擎为JS解释器, 把文档存储成bson结构,在查询时,转换为JS对象,并可以通过熟悉的js语法来操作.
- mongodb数据库bin目录下的文件意义
二、 mongo和传统型数据库的区别
- 传统型数据库: 结构化数据, 定好了表结构后,每一行的内容,必是符合表结构的,就是说列的个数,类型都一样.
- mongo文档型数据库: 集合中存储的每篇文档,都可以有自己独特的结构
(json对象都可以有自己独特的属性和值) - mongo数据库的collection不用提前创建(可以使用时自动创建)。关系型数据库的表必须提前创建
三、 MongoDB服务端与客户端
1、安装之后先建文件夹
2、启动
服务端:相当于启动这个数据库,比如启动mongo,mysql,启动之后,你才能进行CRUD操作。
- 服务端开启方法:
mongod --dbpath D:\ProgramData\MongoDB\Server\3.4\data\db
--dbpath后跟的是上面创建的数据库存储的目录
出现下图①所示表示启动成功,若想和②一样在根目录下启动需要配置环境变量
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200410211749994.png
- cmd开启,开启之后这个cmd窗口就相当于一个服务端程序,你不能关闭,关闭之后数据库就关闭了。
- 进行配置,让数据库的自动运行
客户端:相当于连接数据库的窗口,连接好之后,就可以进行CRUD操作。
CRUD :
crud是指在做计算处理时的
增加(Create)
读取(Retrieve)
更新(Update)
删除(Delete)
几个单词的首字母简写。
crud主要被用在描述软件系统中数据库或者持久层的基本操作功能
四、常用命令
show dbs //查看当前的数据库
use dbname //选择使用的库,Mongodb的库是隐式创建,如果use一个不存在的库,再在该库下创建表格,即可创建库
show collections/show tables //查看当前库下的表格
db.createCollection(‘collectionName’) //创建集合
db.collectionName.insert({name:'haha'}) //插入一条数据亦可以隐式创建集合
db.collectionName.drop() //删除集合,数据库中的集合都删除之后,数据库会自动删除
db.dropDatabase() //删除数据库
五、增删改查
1.增 insert
-
增加单个文档
db.表名.insert({name:’hehe’})
-
增加单个文档,并指定_id
db.表名.insert({_id:8,age:22,name:’zs’})
-
增加多个文档
db.python.insert([{_id:2,name:'lisi',age:18},{name:'ww',age:22,hobby:'sing'}])
2、删除 remove
-
语法
db.表名.remove(查询表达式, 选项) 选项是指 {justOne:true/false},是否只删一行, 默认为false
-
注意
1、查询表达式依然是个json对象{age:20} 2、查询表达式匹配的行将被删除 3、如果不写查询表达式,表中的所有文档将被删除
-
实例
例1、删除sub表中的name属性值为‘语文’的文档 db.sub.remove({name:'语文'}) 例2、删除python表中name属性为‘bb’的文档,只删除一行 db.python.remove({name:'bb'},{justOne:true})
3、更新 update
-
语法
db.collection.update(查询表达式,新值,选项) 如果新值这里放的一条文档,结果是新文档替换旧文档,而不是更新字段,见下图 所以更新操作需要配合更新表达式: $set 修改某列的值;如果新值更新的字段不存在,就会在该条数据后插入新值的字段 $unset 删除某个列 $rename 重命名某个列 $inc 增长某个列 选项有两个参数{upsert:true/false,multi:true/false} upsert:默认false,如果值为true的话,查询表达式未找到该条数据,则直接插入该行 multi: 是指修改多行(即使查询表达式命中多行,默认false,只改1行,如果想改多行,用true)
- $set和选项中的upsert 修改某列的值;或者是给该条数据添加新字段
- $unset 删除数据中的某一列
- $rename 重命名某列的名称
- $inc和选项中的multi : 增长某列的值,multi为true是修改查询出的多行,为false的话是修改一行
4、find 查询
- 语法:db.collection.find(查询表达式,查询的列)
查询的列:{列名:1,列名2:0}
0表示不显示,1表示显示
> db.demo.find() //什么都不写,默认查询全部并显示
{ "_id" : 2, "age" : 22, "hobby" : "dance", "name" : "bbb" }
{ "_id" : 3, "age" : 43, "newname" : "ccc" }
{ "_id" : 4, "name" : "ddd", "age" : 44 }
{ "_id" : 5, "name" : "eee", "age" : 60 }
{ "_id" : 6, "name" : "aaa", "age" : 71 }
> db.demo.find({},{_id:0,name:1,age:1}) //_id字段默认显示,所以改为0,让name和age字段显示
{ "age" : 22, "name" : "bbb" }
{ "age" : 43 }
{ "name" : "ddd", "age" : 44 }
{ "name" : "eee", "age" : 60 }
{ "name" : "aaa", "age" : 71 }
> db.demo.find({_id:2,name:'bbb'},{_id:1,name:1,age:1}) //查询_id为2并且name为bbb的数据,并显示name和age字段
{ "_id" : 2, "age" : 22, "name" : "bbb" }
-
常用方法
limit() 限制输出条数 skip() 跳过几条数据 sort() 将数据排序(-1逆序输出,1正序输出) count() 计数
> db.demo.find() //查询所有的数据
{ "_id" : 2, "age" : 22, "hobby" : "dance", "name" : "bbb" }
{ "_id" : 3, "age" : 43, "name" : "ccc" }
{ "_id" : 4, "name" : "ddd", "age" : 44 }
{ "_id" : 5, "name" : "eee", "age" : 60 }
{ "_id" : 6, "name" : "aaa", "age" : 71 }
> db.demo.find().limit(3) //限制输出3条数据
{ "_id" : 2, "age" : 22, "hobby" : "dance", "name" : "bbb" }
{ "_id" : 3, "age" : 43, "name" : "ccc" }
{ "_id" : 4, "name" : "ddd", "age" : 44 }
> db.demo.find().skip(2).limit(2) //跳过2条数据,并限制输出2条数据,可以实现分页功能
{ "_id" : 4, "name" : "ddd", "age" : 44 }
{ "_id" : 5, "name" : "eee", "age" : 60 }
> db.demo.find().sort({age:-1}) //将age字段逆序输出
{ "_id" : 6, "name" : "aaa", "age" : 71 }
{ "_id" : 5, "name" : "eee", "age" : 60 }
{ "_id" : 4, "name" : "ddd", "age" : 44 }
{ "_id" : 3, "age" : 43, "name" : "ccc" }
{ "_id" : 2, "age" : 22, "hobby" : "dance", "name" : "bbb" }
> db.demo.find().sort({name:1}) //将name字段正序输出
{ "_id" : 6, "name" : "aaa", "age" : 71 }
{ "_id" : 2, "age" : 22, "hobby" : "dance", "name" : "bbb" }
{ "_id" : 3, "age" : 43, "name" : "ccc" }
{ "_id" : 4, "name" : "ddd", "age" : 44 }
{ "_id" : 5, "name" : "eee", "age" : 60 }
> db.demo.find().count() //对查询的数据计数
5
> db.demo.find({_id:{$gt:3}}).count() //查询_id的值大于3的数据的数量
3
查询表达式
$lt 小于
$lte 小于等于
$gt 大于
$gte 大于等于
$ne 不等于
$nin 查询不在某个数组中的文档(not in)
$all 查询包含某个给定数组中所有项的文档
$in 查询包含某个给定数组中某一项的文档
$exists 查询出包含某个字段的文档
$nor 返回所有条件都不满足的文档 {$nor:[条件1,条件2,...]}
$and 返回所有条件都满足的文档 {$and:[条件1,条件2,...]}
$or 返回满足任何一个条件的文档 {$or:[条件1,条件2,...]}
> db.demo.find()
{ "_id" : 2, "age" : 22, "hobby" : "dance", "name" : "bbb" }
{ "_id" : 3, "age" : 43, "name" : "ccc" }
{ "_id" : 4, "name" : "ddd", "age" : 44 }
{ "_id" : 5, "name" : "eee", "age" : 60 }
{ "_id" : 6, "name" : "aaa", "age" : 71 }
> db.demo.find({_id:{'$ne':3}}) //查询_id不等于3的数据
{ "_id" : 2, "age" : 22, "hobby" : "dance", "name" : "bbb" }
{ "_id" : 4, "name" : "ddd", "age" : 44 }
{ "_id" : 5, "name" : "eee", "age" : 60 }
{ "_id" : 6, "name" : "aaa", "age" : 71 }
> db.demo.find({_id:{'$gte':3}}) //查询_id大于等于3的数据
{ "_id" : 3, "age" : 43, "name" : "ccc" }
{ "_id" : 4, "name" : "ddd", "age" : 44 }
{ "_id" : 5, "name" : "eee", "age" : 60 }
{ "_id" : 6, "name" : "aaa", "age" : 71 }
> db.demo.find({_id:{'$nin':[2,3,6]}}) //查询_id不在2,3,6中的数据
{ "_id" : 4, "name" : "ddd", "age" : 44 }
{ "_id" : 5, "name" : "eee", "age" : 60 }
//此处代码和上面分开
> db.demo.find()
{ "_id" : 2, "age" : 22, "hobby" : [ "b", "c", "d" ], "name" : "bbb" }
{ "_id" : 3, "age" : 43, "name" : "ccc", "hobby" : [ "b", "c", "d" ] }
{ "_id" : 4, "name" : "ddd", "age" : 44 }
{ "_id" : 5, "name" : "eee", "age" : 60, "hobby" : [ "a", "b", "c" ] }
{ "_id" : 6, "name" : "aaa", "age" : 71, "hobby" : [ "a", "b", "c" ] }
> db.demo.find({hobby:{$all:['a','c']}}) //查询爱好包含a和c的数据
{ "_id" : 5, "name" : "eee", "age" : 60, "hobby" : [ "a", "b", "c" ] }
{ "_id" : 6, "name" : "aaa", "age" : 71, "hobby" : [ "a", "b", "c" ] }
> db.demo.find({hobby:{$in:['a','c']}}) //查询爱好包含a或c的数据
{ "_id" : 2, "age" : 22, "hobby" : [ "b", "c", "d" ], "name" : "bbb" }
{ "_id" : 3, "age" : 43, "name" : "ccc", "hobby" : [ "b", "c", "d" ] }
{ "_id" : 5, "name" : "eee", "age" : 60, "hobby" : [ "a", "b", "c" ] }
{ "_id" : 6, "name" : "aaa", "age" : 71, "hobby" : [ "a", "b", "c" ] }
> db.demo.find({hobby:{$exists:0}}) //值为0查询不包含hobby字段的文档,为1的话就是包含hobby字段的文档
{ "_id" : 4, "name" : "ddd", "age" : 44 }
> db.demo.find({$nor:[{_id:{$gt:3}},{age:{$lt:40}}]}) //查询_id不大于3并且age不小于40的
{ "_id" : 3, "age" : 43, "name" : "ccc", "hobby" : [ "b", "c", "d" ] }
> db.demo.find({$and:[{_id:{$gt:3}},{age:{$lt:61}}]}) //s查询_id大于3并且age小于61的
{ "_id" : 4, "name" : "ddd", "age" : 44 }
{ "_id" : 5, "name" : "eee", "age" : 60, "hobby" : [ "a", "b", "c" ] }
> db.demo.find({$or:[{_id:{$gt:3}},{age:{$lt:40}}]}) //查询_id大于3或者age小于40的
{ "_id" : 2, "age" : 22, "hobby" : [ "b", "c", "d" ], "name" : "bbb" }
{ "_id" : 4, "name" : "ddd", "age" : 44 }
{ "_id" : 5, "name" : "eee", "age" : 60, "hobby" : [ "a", "b", "c" ] }
{ "_id" : 6, "name" : "aaa", "age" : 71, "hobby" : [ "a", "b", "c" ] }
5、聚合查询 aggregate
MongoDB中聚合(aggregate)主要用于处理数据(诸如统计平均值,求和等),并返回计算后的数据结 果。有点类似sql语句中的 count(*)。
MongoDB的聚合管道将MongoDB文档在一个管道处理完毕后将结果传递给下一个管道处理,管道操作是 可以重复的
-
语法
db.COLLECTION_NAME.aggregate([{管道1},{管道2},{管道3}, ... ]) 常用管道操作 $match:用于过滤数据,只输出符合条件的文档。*** $limit:用来限制MongoDB聚合管道返回的文档数。 $skip:在聚合管道中跳过指定数量的文档,并返回余下的文档。 $group:将集合中的文档分组,可用于统计结果。** $sort:将输入文档排序后输出 group中的一下操作表达式: $sum 计算总和 $avg 计算平均值 $min 获取集合中所有文档对应值的最小值。 $max 获取集合中所有文档对应值的最大值。 $first 根据文档的排序获取第一个文档 $last 根据文档的排序获取最后一个文档
-
练习
1. 查询每个栏目下的商品数量(必须以_id命名,$cat_id意思是以cat_id这一列分组)
> db.goods.aggregate([{$group:{_id:'$cat_id',t:{$sum:1}}}])
{ "_id" : 14, "t" : 2 }
{ "_id" : 2, "t" : 1 }
{ "_id" : 13, "t" : 2 }
{ "_id" : 3, "t" : 15 }
{ "_id" : 11, "t" : 2 }
{ "_id" : 8, "t" : 3 }
{ "_id" : 4, "t" : 3 }
{ "_id" : 5, "t" : 1 }
{ "_id" : 15, "t" : 2 }
2、查询goods下有多少条商品(null就是不以某一列分组)
> db.goods.aggregate([{$group:{_id:null,t:{$sum:1}}}])
{ "_id" : null, "t" : 31 }
3、查询每个栏目下价格大于50元的商品个数
> db.goods.aggregate([{$match:{shop_price:{$gt:50}}},{$group:{_id:'$cat_id',t:{$sum:1}}}])
{ "_id" : 14, "t" : 1 }
{ "_id" : 2, "t" : 1 }
{ "_id" : 3, "t" : 15 }
{ "_id" : 8, "t" : 3 }
{ "_id" : 15, "t" : 1 }
{ "_id" : 5, "t" : 1 }
{ "_id" : 4, "t" : 3 }
4、查询每个栏目下的库存量
> db.goods.aggregate([{$group:{_id:'$cat_id',t:{$sum:'$goods_number'}}}])
{ "_id" : 14, "t" : 9 }
{ "_id" : 2, "t" : 0 }
{ "_id" : 13, "t" : 4 }
{ "_id" : 3, "t" : 203 }
{ "_id" : 11, "t" : 23 }
{ "_id" : 8, "t" : 61 }
{ "_id" : 4, "t" : 3 }
{ "_id" : 5, "t" : 8 }
{ "_id" : 15, "t" : 2 }
5、查询每个栏目下价格大于50元的商品个数 ,并筛选出满足条件的商品个数大于等于3的栏目
> db.goods.aggregate([{$match:{shop_price:{$gt:50}}},{$group:{_id:'$cat_id',t:{$sum:1}}},{$match:{t:{$gte:3}}}])
{ "_id" : 3, "t" : 15 }
{ "_id" : 8, "t" : 3 }
{ "_id" : 4, "t" : 3 }
6、查询每个栏目下的库存量,并按库存量排序(1是正序,‐1是逆序)
db.goods.aggregate([{$group:{_id:"$cat_id" , total: {$sum:"$goods_number"}}}, {$sort:{total:1}}])
7.查询每个栏目的商品平均价格,并按平均价格由高到低排序
db.goods.aggregate([{$group:{_id:"$cat_id",avg:{$avg:"$shop_price"}}},{$s ort:{avg:‐1}}])