MongoDB简介
- MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。
- MongoDB是一个介于关系数据库和非关系数据库(nosql)之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。
数据库命令
- 数据库不需要提前创建,use后,插入数据的时候会自动创建
- 查看当前的数据库:
db
- 查看所有的数据库:
show dbs/show databases
- 切换数据库:
use db_name
- 删除当前的数据库:
db.dropDatabase()
集合命令
- 不手动创建集合:向不存在的集合中第一次加入数据时,集合会被创建出来
- 手动创建集合:
db.createCollection(name, options)
db.createCollection("stu")
db.createCollection("stu", {capped:true, size:10})
- 参数capped:默认值为false表示不设置上限,值为true表示设置上限
- 参数size:当capped的值为true时,需要指定此参数,表示上限的大小,当文档达到上限时,会将之前的数据覆盖掉,单位为字节
- 查看集合:
show collections
- 删除集合:
db.col_name.drop()
MongoDB中常见的数据类型
常见类型:
- Object ID:文档ID
- String:字符串,最常用,必须是有效的UTF-8
- Boolean:存储一个布尔值,true或者false
- Integer:整数可以是32或者64位,这取决于服务器
- Double:存储浮点值
- Arrays:数组或列表,多个值存储到一个键
- Object:用于嵌入式的文档,即一个值为一个文档
- Null:存储Null值
- Timestamp:时间戳,表示从2070-1-1到现在的总秒数
- Data:存储当前日期或时间的UNIX时间格式
注意点
- 创建日期的语句如下:参数的格式为YYYY-MM-DD
new Data('2017-12-20')
-
每一个文档都有一个属性:
_id
,保证每个文档的唯一性- 自己可以去设置_id插入文档,如果没有提供,那么MongoDB为每个文档提供了一个独特的_id,类型为Object ID。
- Object ID是一个12字节的16进制数,每个字节两位,一共是24位字符串:前4个字节为当前时间戳,接下来3个字节的机器ID,接下来的2个字节中MongoDB的服务器进程id,最后3个字节是简单的增量值。
MongoDB数据库中的增删改查
- 插入命令:
ds.col_name.insert({key:value})
- 插入文档时,如果不指定_id参数,MongoDB会为文档分配一个唯一的Object ID
- 保存命令:
ds.col_name.save(document)
如果文档的_id已经存在,则修改数据中的键和值;如果_id不存在,则添加。 -
insert() 和 save() 的区别:
- insert 插入,_id重复报错
- save保存,_id存在会更新,不存在,会插入
- 简单查询:
ds.col_name.find()
- 更新命令:
ds.col_name.update(query条件, 修改操作, {multi: })
- 参数query:查询条件
- 参数update:更新操作符
- 参数multi:可选,默认是false,表示只更新找到的第一条数据,值为true表示把满足条件的文档全部更新。
db.stu.update({name1:'hr'}, {name2:'mnc'}}) # 更新一条 # 且为覆盖操作:{name2:'mnc'}将{name1:'hr'}覆盖掉 # $set:根据键更新对应的值 db.stu.update({name:'hr'}, {$set:{name:'hys'}}) # 更新一条 db.stu.update({}, {$set:{gender:0}}, {multi:true}) # 更新全部
-
注意:有无 $set 的区别:
- 无 $set时:会把满足条件的数据,更新(覆盖)为 修改操作的数据
- $set 存在时:会把满足条件的数据,根据“ 键 ”更新对应的值。
- 且{multi:true}仅在 operators"
- 删除命令:
db.col_name.remove(query, {justOne: })
- 参数query:删除的文档的条件
- 参数justOne:可选,如果设置为true或1,则只删除一条,默认为false,表示删除多条。
MongoDB的高级查询
-
数据查询
- 方法find():查询
db.col_name.find({条件文档})
- 方法findOne():查询,只返回第一个结果
db.col_name.findOne({条件文档})
- 方法pretty():将结果格式化,是查询结果更加美观,类似于pprint()
db.col_name.find({条件文档}).pretty()
- 方法find():查询
-
比较运算符
- 等于:默认是等于判断,没有运算符
-
小于:
$lt (less than)
-
小于等于:
$lte (less than equal)
-
大于:
$gt (greater than)
-
大于等于:
$gte (greater than equal)
-
不等于:
$ne (not equal)
- 例如:
查询年龄大于18的所有学生 db.stu.find({age: {$gte:18}})
- 例如:
-
逻辑运算符
- 逻辑运算符主要指的是与、或 逻辑。
-
and:在json中写多个条件即可
查询年龄大于或等于18,并且性别为true的学生 db.stu.find({age:{$gte:18}, gender:true})
-
or:需要使用
$or
,值为==数组==,数组中每个元素为json查询年龄大于18,或性别为false的学生 db.stu.find({$or: [{age:{$gt:18}}, {gender:false}]}) 查询年龄大于18或性别为true,并且名字为郭靖 db.stu.find({$or:[{age:{$gt:18}},{gender:true}], name:"郭靖"})
-
范围运算符:
- 使用
$in
、$nin
判断数据是否在某个数组内查询年龄为18、28、38的学生 db.stu.find({age:{$in:[18,28,38]}})
- 使用
-
支持正则表达式
- 使用
//
或$regex
编写正则表达式查询sku以abc开头的数据 db.col_name.find({sku:/^abc/}) 查询sku以789结尾的数据 db.col_name.find({sku:{$regex:"789$"}})
- 使用
-
使用 skip和 limit
- limit()方法:用于读取指定数量的文档
db.col_name.find().limit(NUMBER) 查询2条学生信息 db.stu.find().limit(2)
- skip()方法:用于跳过指定数量的文档
db.col_name.find().skip(NUMBER) db.stu.find().skip(2)
-
同时使用:
db.stu.find().limit(4).skip(5) 或 db.stu.find().skip(5).limit(4)
- 注意:先试用skip,再使用limit的效率要高于前者
- limit()方法:用于读取指定数量的文档
-
自定义查询(了解)
- 由于MongoDB的shell是一个js的执行环境,使用$where后面写一个函数,返回瞒住条件的数据
查询年龄大于30的学生 db.stu.find({ $where:function(){ return this.age>30; } })
- 由于MongoDB的shell是一个js的执行环境,使用$where后面写一个函数,返回瞒住条件的数据
-
投影
- 在查询到的返回结果中,只选择必要的字段
- 命令:
db.col_name.find({条件文档}, {字段名称:1,...})
- 参数为字段的值,值1表示显示,值0表示不显示
- 特别注意:对于_id列默认是显示的,如果不显示需要明确设置为0
- 示例:
db.stu.find({},{_id:0,name:1,gender:1})
-
排序
- 方法sort(),用于对 集进行排序
- 命令:
db.col_name.find().sort({字段:1,...})
- 参数1为升序排列,参数-1位降序排列
根据性别降序,再根据年龄升序 db.stu.find().sort({gender:-1,age:1})
-
统计个数
- 方法count() 用于统计结果集中文档条数
- 命令:
db.col_name.find({条件}).count()
- 命令:
db.col_name.count({条件})
db.stu.find({gender:true}).count() 或 db.stu.count({age:{$gt20},gender:true})
- 注意:先find再count的时候,条件是不能写在count里面的,负责统计结果错误。
-
消除重复
- 方法distinct() 对数据进行去重,返回结果为数组
- 命令:
db.col_name.distinct('去重字段',{条件})
- 示例:
db.stu.distinct('hometown',{age:{$gt:18}})
MongoDB的聚合操作
- MongoDB的聚合是什么
- 聚合是基于数据处理的聚合管道,每一个文档通过一个由多个阶段组成的管道,可以对每个阶段的管道进行分组、过滤等功能,然后经过一系列的处理,输出相应的结果。
- 语法:
db.col_name.aggregate({管道:{表达式}})
常用管道命令
- 在MongoDB中,文档处理完毕后,通过管道进行下一次处理,常用管道命令如下:
-
$group
:将集合中的文档分组,可用于统计结果 -
$match
:过滤数据,只输出符合条件的文档 -
$project
:修改输入文档的结构,如重命名、增加、删除字段、创建计算结果 -
$sort
:将文档排序后输出 -
$limit
:限制聚合管道返回的文档数 -
$skip
:跳过指定数量的文档,并返回余下的文档
-
常用表达式
- 表达式:处理输入文档并输出。语法:`表达式:'$列名'
-
$sum
:计算总和,$sum:1
表示以1计数。 -
$avg
:计算平均值 -
$min
:获取最小值 -
$max
:获取最大值 -
$push
:在结果文档中插入值到一个数组中
-
管道命令之 $group
-
按照单个字段进行分组:
-
$group
是所有聚合命令中用的最多的一个命令,用来将集合中的文档分组,可用于统计结果,使用示例如下:db.stu.aggregate( {$group: { _id:"$gender", counter:{$sum:1} total_age:{$sum:"$age"} } } )
- 其中注意点:
-
db.col_name.aggregate
是语法,所有的管道命令都要写在其中 -
_id
表示分组的依据,按照哪个字段进行分组,需要使用$gender
表示选择这个字段进行分组。 -
$sum:1
表示把每一条数据作为1进行统计,统计的是该分组下面数据的条数。 -
$age
取age对应的值 -
$sum:"$age"
表示获取每组中age字段的总和。 -
$group
中对应字典中的键,是输出数据的键。
-
- 其中注意点:
-
-
按照多个字段进行分组
- 在
_id
字段 后面 写上进行分组字段的字典db.stu.aggreagate( {$group: { _id:{name:"$name",age:"$age"}, counter:{$sum:1} } } )
- 在
-
统计整个文档(不分组 group by null)
- 当我们需要统计整个文档的时候,
$group
的另一种用途就是把整个文档分为一组进行统计,使用示例如下:db.stu.aggregate( {$group: { _id:null, counter:{$sum:1} } } )
- 其中注意点:
-
_id: null
表示不指定分组的字段,即统计整个文档,此时获取的counter
表示整个文档的个数。
-
- 其中注意点:
- 当我们需要统计整个文档的时候,
-
数据透视
- 把不同行的数据,放到一行来展示
- 正常情况下在统计的不同性别的数据的时候,需要知道所有的name,需要逐条观察,如果通过某种方式把所有name放到一起,那么就可以理解为数据透视。使用示例如下:
- 统计不同性别的学生:
db.stu.aggregate( {$group: { _id:null, name:{$push:"$name"} } } )
-
使用
$$ROOT
可以将整个文档放入到数组中。db.stu.aggregate( {$group: { _id:null, name:{$push:"$$ROOT"} } } )
当某个键对应的值是一个字典的时候,取其字典中的值需要使用.
(点)操作
$_id.country
表示:取_id
键对应字典下的country
键对应值
管道命令之 $match
-
$match
用于进行数据的过滤,是在能够聚合操作中使用的命令,和find
的区别在于$match
把结果交给下一个管道处理,而find
不行。- 查询年龄大于20的学生
db.stu.aggregate( {$match:{age:{$gt:20}} } )
- 查询年龄大于20的男女学生人数
db.stu.aggregate( {$match:{age:{$gt:20}}}, {$group:{_id:"$gender",count:{$sum:1}}} )
- 查询年龄大于20的学生
管道命令之 $project
-
$project
用于修改文档的输入输出结构,例如重命名,增加,删除字段。 - 参数为字段的值,值1表示显示,值0表示不显示
-
特别注意:对于_id列默认是显示的,如果不显示需要明确设置为0
- 查询学生的年龄、姓名,仅输出年龄姓名
db.stu.aggregate( {$project:{_id:0,name:1,age:1} } )
- 查询男女生人数,输出人数,直接添加name字段
db.stu.aggregate( {$group:{_id:"$gender",count:{$sum:1}}}, {$project:{_id:0,countet:1,name:"$_id"}} )
- 查询学生的年龄、姓名,仅输出年龄姓名
管道命令之 $sort
-
sort
用于将输出文档排序后输出 - 参数1为升序排列,参数-1位降序排列
- 查询学生信息,安装年龄升序
db.stu.aggregate({$sort:{age:1}})
- 查询男女人数,按照人数降序
db.stu.aggregate( {$group:{_id:"$gender",count:{$sum:1}}}, {$sort:{count:1}} )
- 查询学生信息,安装年龄升序
管道命令之 limit
-
$limit
限制返回数据的条数 -
$skip
跳过指定的文档树,返回剩下的文档数量 - 同时用时时候,先试用skip,再使用limit
- 查询2条学生信息
db.stu.aggregate({$limit:2})
- 查询从第三条开始的学生信息
db.stu.aggregate({$skip:2})
- 统计男女生人数,按照人数升序,返回第二条数据
db.stu.aggregate( {$group:{_id:"$gender",count:{$sum:1}}}, {$sort:{count:1}}, {$skip:1} {$limit:1} )
- 查询2条学生信息
网友评论