目录
- 文档修改器
- 数组修改器
- 时间数据类型
- 其他数据类型
- 索引
- 索引类型
- 聚合操作
- 聚合管道
1. 文档修改器
修改操作符(修改器)
$set
作用: 修改一个域的值 / 增加一个域
eg: db.class.update({name:'Lily'},{$set:{age:17}}) #Lily age 改为17
db.class.update({name:'Jame'},{$set:{sex:'m'}}) #增加Jame 的 sex 域
$unset
作用: 删除一个域
eg:db.class.update({name:'Abby'},{$unset:{sex:''}}) #删除Abby的sex域
$rename
作用: 修改域的名称
eg:db.class.update({},{$rename:{sex:'gender'}},false,true) #将所有文档sex域改为gender
$setOnInsert
作用: 如果使用update插入了文档, 则将该修改器内容作为插入文档的一部分
eg:db.class.update({name:'Jame'},{$set:{age:18},
$setOnInsert:{gender:'m',tel:'123456'}},true)
#当原集合中没有Jame的文档时,执行插入操作, 此时setOnInsert后内容生效
若存在此文档, 则只执行set部分
$inc 加法修改器
作用: 域的值加响应的数(整数; 负数; 小数)
eg: db.class.update({},{$inc:{age:1}},false,true) #所有人年龄加1
$mul 乘法修改器
作用: 域的值乘响应的数(整数; 负数; 小数)
eg: db.class.update({},{$mul:{age:2}},false,true) #所有人年龄乘2
$min (给出域的上限)
作用: 如果筛选文档的指定域值小于min值则不修改, 如果大于min值则修改为min值
eg:db.class.update({name:'Levi'},{$min:{age:20}})
$max (给出域的下限)
作用: 如果筛选文档的指定域值大于max值则不修改, 如果小于max值则修改为max值
eg:db.class.update({name:'Lenzer'},{$max:{age:19}})
2. 数组修改器
数组修改器
$push / $pushALL
作用: 向数组中添加一项 / 多项
eg:db.class1.update({name:'小红'},{$push:{score:91}}) #给小红score数组中添加一项
db.class1.update({name:'小乔'},{$pushAll:{score:[94,10]}}) #给小乔score数组中添加[94,10]
$pull / $pullAll
作用: 从数组中删除一项 / 多项
eg: db.class1.update({name:'小红'},{$pull:{score:78}}) #从小红score数组中删除78
db.class1.update({name:'小乔'},{$pullAll:{score:[92,10]}}) #从小乔score数组中删除[92,10]
$each
作用: 对多个值逐个进行操作
eg: db.class1.update({name:'小乔'},{$push:{score:{$each:[99,10]}}}) #相当于进行了两次push操作
注: 有一些功能的操作必须要配合 each 完成
$position 作用: 指定插入位置
eg:#给小明的 "score" : [ 88, 89 ] ,88后插入67
db.class1.update({name:'小明'},{$push:{score:{$each:[67],$position:1}}})
$sort 作用: 数组排序
eg:db.class1.update({},{$push:{score:{$each:[],$sort:-1}}}) #给score数组进行排序(-1:升序)
$pop 作用:
作用: 弹出一项, *只能从数组两端删除(1 最后一项,-1 第一项)
eg:db.class1.update({name:'小乔'},{$pop:{score:1}})#弹出小乔score域数组中最后一项
$addToSet
作用: 向数组中添加一项, 但是不能添加重复的内容
eg: db.class1.update({name:'小刚'},{$addToSet:{score:88}}) #小刚score数组中原有88项, 不会添加
db.class1.update({name:'小刚'},{$addToSet:{score:81}}) #添加 81
3. 时间数据类型
mongo 中存储时间大多为 ISODate (格林尼治时间)
存储当前时间方法:
1. new Date() 自动生成当前时间
eg:db.class2.insert({book:'python入门',date:new Date()})
2. ISODate() 自动生成当前时间
eg:db.class2.insert({book:'python精通',date:ISODate()})
3.Date() 将系统时间转换为字符串
eg: db.class2.insert({book:'python疯狂',date:Date()})
指定时间 :
ISODate()
功能: 生成mongo标准时间类型数据
参数: 如果不传参默认为当前时间, 传参表示指定时间
"YYYY-MM-DD HH:MM:SS"
"YYYYMMDD HH:MM:SS"
"YYYYMMDD"
eg:db.class2.insert({book:'python崩溃',date:Date("2019-01-01 12:12:12")})
时间戳:
valueOf() 作用: 获取某个时间的时间戳
eg:db.class2.insert({book:'Python涅槃',date:ISODate().valueOf()}) #当前标准时间时间戳
4. 其他数据类型
Null 类型:
值 null
1. 如果某个域存在却没有值,可以赋值为null
eg: db.class2.insert({book:'Python死去活来',price:null})
2. 查找时null可以查找文档没有该域
eg: db.class2.find({date:null})
Object 类型 (内部文档)
文档内部某个域的值还是一个文档数据, 则这个文档就是内部文档数据
通常使用 "外部文档域名.引用内部文档域名" 的方式使用内部文档
eg: db.class3.insert({name:'鲁迅',sex:'m',book:{title:'狂人日记',price:46.8}})
>db.class3.find({"book.title":'狂人日记'},{_id:0})
eg:db.class3.update({"book.title":'围城'},{$set:{"book.price":48.8}})
数组也可使用".下标"方式操作
eg:db.class1.find({"score.0":{$gt:90}},{_id:0})
>db.class1.update({name:"小刚"},{$set:{"score.1":80}})
练习:
grade数据库:
使用之前的grade数据库
1. 将小红年龄改为12岁,兴趣爱好变为跳舞画画
update({$set:{age:12,hobby:['draw','dance']}})
2. 追加小明爱好唱歌
{$push:{hobby:'sing'}}
3. 追加小王兴趣爱好 吹牛 打篮球
{$pushAll:{hobby:[‘吹牛’,'basketball']}}
4. 小李兴趣多了跑步和唱歌,但是要确保和以前不重复
{$addToSet:{hobby:{$each:['running','sing']}}}
5. 将班级所有男同学年龄加1
update({sex:'m'},{$inc:{age:1}},false,true)
6. 删除小明的sex属性
{$unset:{sex:''}}
7. 修改小刘的年龄为15,如果不存在该同学则添加,同时 要添加兴趣爱好和性别男
update({name:'小刘'},{$set:{age:15},$setOnInsert:{sex:'m',hobby:['dance','computer']}},true)
8. 删除小李兴趣中的第一项
{$pop:{hobby:-1}}
9. 删除小红爱好中的画画和跳舞
{$pullAll:{hobby:[‘draw’,‘dance’]}}
5. 索引
索引 index :
建立指定键值及所在文档储存位置的对照清单
使用索引可以方便我们进行快速查找
减少遍历次数, 提高查找效率
Mongo 中的索引方法:
db.collection_name.ensureIndex()
功能: 创建索引
参数: 索引域和索引选项
eg: db.class.ensureIndex({name:1}) #对 name 域创建索引 (1: 正序索引 -1: 逆序索引)
查看集合中的索引
db.collection_name.getIndexes()
自定义索引名称
db.collection_name.ensureIndex({}, {name:'indexName'})
eg:db.class.ensureIndex({age:1},{name:'ageIndex'})#对age创建名词为ageIndex的正向索引
删除索引:
db.collection_name.dropIndex("index")
功能: 删除索引
参数: 要删除的索引名称或键值对
eg:db.class.dropIndex({name:1}) / db.class.dropIndex("ageIndex")
db.collection.dropIndexes()
功能: 删除所有索引
注: _id 是系统自动创建的主键索引, 不会删除
6. 索引类型
索引类型:
复合索引
根据多个域创建一个索引
eg: db.class.ensureIndex({name:1,age:-1},{name:"name_age"})
数组索引 / 子文档索引
如果对某个域的值为数组或子文档的域创建索引
那么通过数组或者子文档中的某一项进行查找也是索引查找
eg:db.class1.ensureIndex({score:1})
>db.class1.find({'score.1':80}) #此时查找为索引查找
唯一索引:
创建索引的域要求值不能重复
eg:db.class.ensureIndex({age:1},{unique:true}) #创建失败,age中有重复值
db.class.ensureIndex({name:1},{unique:true}) #对name创建唯一索引
>db.class.insert({name:'Jame'}) #此时插入重复值时报错
稀疏索引 / 间隙索引:
只针对有指定索引域的文档创建索引, 没有该域的文档不会插入到索引表
eg:db.class.ensureIndex({age:1},{sparse:true})
索引约束:
1. 索引表需要占用一定的数据库磁盘空间
2. 当对数据进行增删改等写入操作时, 索引也需要更新, 降低了数据修改的效率
综上: 数据量较小时不适合创建索引
当数据库进行频繁的修改操作而不是查找操作时也不适合创建索引
针对一个集合并不是创建索引越多越好
7. 聚合操作
聚合操作:
对文档的筛选结果进行整理统计
db.collection_name.aggregate()
功能: 完成聚合操作
参数: $group:{聚合条件,聚合操作符}
聚合操作符:
$group 分组聚合 需要配合具体的分组统计选项
统计选项:
$sum : 求和
eg: #按性别分组,求各组人数和 sum:1 每统计一项 +1
db.class.aggregate({$group:{_id:'$gender',num:{$sum:1}}})
#统计所有男生和女生年龄总和
db.class.aggregate({$group:{_id:'$gender',num:{$sum:'$age'}}})
$avg : 求平均数
eg:#按性别分组, 求平均年龄
eg: db.class.aggregate({$group:{_id:'$gender',avg:{$avg:'$age'}}})
$max : 求最大值
eg: db.class.aggregate({$group:{_id:'$gender',max:{$max:'$age'}}})
$min : 求最小值
eg: db.class.aggregate({$group:{_id:'$gender',min:{$min:'$age'}}})
$project
作用: 修改文档的显示效果
eg: db.class.aggregate({$project:{_id:0,name:1,age:1}}) #同find({},{_id:0,name:1,age:1}})
db.class.aggregate({$project:{_id:0,名字:'$name',年龄:'$age'}})
$match
作用: 数据筛选
$match值的用法同 query
eg: db.class.aggregate({$match:{'age':{$gt:18}}}) #查找年龄大于18的文档
$limit
作用: 筛选前几条文档
eg: db.class.aggregate({$limit:3})
$skip
作用: 跳过几条文档显示
eg: db.class.aggregate({$skip:3})
$sort
作用: 将数据排序, 支持单个排序和符合排序
eg: db.class.aggregate({$sort:{age:1}}) #按照姓名升序排序
db.class.aggregate({$sort:{age:1,name:1}})
8. 聚合管道
聚合管道:
将上一个聚合的操作结果给下一个聚合继续操作
db.collection_name.aggregate([{聚合1},{聚合2},...])
eg:#所有男生安装年龄升序排序,不显示_id
db.class.aggregate([{$match:{gender:'m'}}, {$project:{_id:0}}, {$sort:{age:1}}])
#找出班级中名字相同的同学
db.class.aggregate([{$group:{_id:'$name',num:{$sum:1}}}, {$match:{num:{$gt:1}}}])