MongoDB 学习(三)
1. 高级操作
- 聚合aggregate
- 聚合(aggregate)主要用于计算数据
- 语法:
db.集合名称.aggregate([{管道:{表达式}}])
- 管道
- 在mongodb中,文档处理完毕后,通过管道进行下一次处理
- $group:将集合中的文档分组,可用于统计结果
- $match:过滤数据,只输出符合条件的文档
- $project:修改输入文档的结构,如重命名、增加、删除字段、创建计算结果
- $sort:将输入文档排序后输出
- $limit:限制聚合管道返回的文档数
- $skip:跳过指定数量的文档,并返回余下的文档
- $unwind:讲数组类型的文档进行拆分
- 表达式
- 处理输入文档并输出
- 语法:
表达式:'$列名'
- 常用表达式
- s u m : 计 算 总 和 , sum:计算总和, sum:计算总和,sum:1同count表示计数
- $avg:计算平均值
- $min:获取最小值
- $max:获取最大值
- $push:在结果文档中插入一个值到一个数组中
- $first:根据资源文档的排序获取第一个文档数据
- $last:根据资源文档的排序获取最后一个文档数据
- $group
- 将集合中的文档分组,可用于统计结果
- 将_id表述分组的依据,使用某个字段的格式为’$字段’
- 例一:
-- 统计男生、女生的总人数 db.集合名称.aggregate([ { $group:{ _id:'$gender', counter:{$sum:1} } } ])
- Group by null
- 将集合中所有文档分为一组
- 例一:
-- 求学生总人数、平均年龄 db.集合名称.aggregate([ {$group: { _id:null, counter:{$sum:1}, avgAge:{$avg:'$age'} } } ])
- 透视数据
- 例一:
-- 统计学生性别及学生姓名 db.集合名称.aggregate([ {$group: { _id:'$gender', name:{$push:'$name'} } } ])
- 例一:
- 使用$$ROOT可以将文档内容加入到结果集的数组中,代码如下:
db.集合名称.aggregate([ {$group: { _id:'$gender', name:{$push:'$$ROOT'} } } ])
- $match
- 用于过滤数据,只输出符合条件的文档
- 使用MongoDB的标准查询操作
- 例一:
-- 查询年龄大于20的学生 db.集合名称.aggregate([ {$match:{age:{$gt:20}} } ])
- 例二:
-- 查询年龄大于20的男生、女生人数 db.集合名称.aggregate({ {$match:{age:{$gt:20}}}, {$group: { _id:'$gender', counter:{$sum:1} } } })
- $project
- 修改输入文档的结构,如重命名、增加、删除字段、创建计算结果
- 例一:
-- 查询学生的姓名、年龄 db.集合名称.aggregate([ {$project: { _id:0, name:1, age:1 } } ])
- 例二:
-- 查询男生、女生人数,输出人数 db.集合名称.aggregate([ {$group: { _id:'$gender', counter:{$sum:1} } }, {$project: { _id:0, counter:1 } } ])
- sort
- 将输入文档排序后输出
- 例一:
-- 查询学生信息,按年龄升序 db.集合名称.aggregate([ {$sort: { age:1 } } ])
- 例二:
-- 查询男生、女生人数,按人数降序 db.集合名称.aggregate([ {$group: { _id:'$gender', counter:{$sum:1} } }, {$sort: { counter:-1 } } ])
- limit
- 限制聚合管道返回的文档数
- 例一:
-- 查询2条学生信息 db.集合名称.aggregate([ {$limit:2} ])
- $skip
- 跳过指定数量的文档,并返回余下的文档
- 例一:
-- 查询从第三条开始的学生信息 db.集合名称.aggregate([ {$skip:2} ])
- 例二:
-- 统计男生、女生人数,按人数升序,取第二条数据 db.集合名称.aggregate([ {$group: { _id:'$gender', counter:{$sum:1} } }, {$sort: { counter:1 } }, {$skip:1}, {$limit:1} ]) -- 注意:先写skip,再写limit
- unwind
- 将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值
- 语法1
- 对某字段值进行拆分
db.集合名称.aggregate([ {$unwind:'$字段名称'} ])
- 对某字段值进行拆分
- 语法2
- 对某字段值进行拆分
- 处理空数组、非数组、无字段、null情况
db.集合名称.aggregate([ {$unwind: { path:'$字段名称', preserveNullAndEmptyArrays:<boolean>#防止数据丢失 } } ]) -- preserveNullAndEmptyArrays为false的情况下,空数组、无字段、null的文档将被丢弃,若不想被丢弃,设为true
- 索引
- 创建大量数据
for(i = 0; i < 100000; i++) { db.集合名称.insert({name:'test' + i, age:i}) }
- 数据查找性能分析
- 查找姓名为test10000的文档
db.集合名称.find({name:'test10000'})
- 使用explain()命令进行查询性能分析
db.集合名称.find({name:'test10000'}).explain('executionStats')
- 查找姓名为test10000的文档
- 建立索引
- 创建索引
db.集合名称.ensureIndex({属性:1})
- 1表示升序,-1表示降序
- 创建索引
- 索引的命令
- 建立唯一索引,实现唯一约束的功能
db.集合名称.ensureIndex({"name":1}, {"unique": true})
- 联合索引,对多个属性建立一个索引,按照find()出现的顺序
db.集合名称.ensureIndex({name:1, age:1})
- 查看文档所有索引
db.集合名称.getIndexes()
- 删除索引
db.集合名称.dropIndexes('索引名称')
- 建立唯一索引,实现唯一约束的功能
- 创建大量数据