NoSQL
“non-relational”或”Not Only SQL”
非关系数据库。数据与数据之间不再有一对一或一对多之类的对应的关系,数据从一个个清晰的条目(如MySQL)变成了一个独立的个体。
MySQL扩展性差,大数据下IO困难,表结构更改困难。MongoDB易扩展,大数据高性能,灵活的数据模型,高可用。
基本操作
1 2 3 4
| db //查看当前数据库 show dbs //查看所有数据库 use db_name //切换数据库 db.dropDatabase() //删除当前数据库
|
1 2 3 4 5 6 7 8 9 10 11 12
| 创建数据库: use db_name 插入数据操作
不手动创建集合: 想不存在的集合第一次插入数据时,集合会被创建出来 手动创建集合: db.createConnection(name,options) db.createCollection("sub",{capped:true,size:10})
show collections db.col_name.drop()
|
1 2
| 创建日期: new Data('2021-09-25')
|
1 2 3 4
| db.col_name.insert({key1:value1,key2:value2}) db.col_name.find() //展示col中所有数据 db.col_name.save(document) //insert插入不会将原有相同_ID相同的数据修改,而save会 db.update(<query>,<update>,{multi:<boolean>}) //三个参数:更新条件,更新操作,默认false,表示只更新第一条,true则更新所有
|
1 2 3 4 5
| //已有数据{"_id":1,"name":"joker","age":19} db.col_name.update({"_id",1},{"name":"joke"}) //此时数据变为{"_id":1,"name":"joke"} db.col_name.update({"_id":1},{$set:{name:"joke"}}) //此时数据变为{"_id":1,"name":"joke","age":19}
//multi update only works with $ operator
|
1
| db.col_name.remove(<query>,{justOne:<boolean>}) //<query>为删除文档的条件(必选),justOne设为1或true,则只删除一条,默认false,表示删除多条
|
1 2 3
| db.col_name.find({条件文档}) db.col_name.findOne({条件文档}) db.col_name.find().pretty() //将结果格式化
|
比较运算符:
- 等于:默认等于
- 小于 $lt (less than)
- 小于等于 $lte (less than equal)
- 大于 $gt (greater than)
- 大于等于 $gte
- 不等于 $ne
1
| db.col_name.find({age:{$gte:18}})
|
范围运算符:
1
| db.stu.find({age:{$in:[18,28,38]}})
|
逻辑运算符:
1
| db.stu.find({$or:[{age:{$gte:16}},{hometown:"hhh"}]})
|
1 2 3
| //正则表达式:使用//或$regex db.products.find({sku:/^abc/}) db.products.find({sku:{$regex:'789$'}})
|
1
| db.col_name.find().limit(NUMBER).skip(NUMBER) //用于读取或跳过指定数量文档,可同时使用
|
1 2 3 4 5 6
| //自定义查询,使用&where后面写一个函数,返回满足条件的数据 db.stu.find({ $where:function(){ retrun this.age>30//this就是当前集合 } })
|
1 2 3
| //投影:在查询返回的结果中,只显示必要的字段 db.col_name.find({},{字段名称:1,...}) //1表示显示,0表示不显示,不能同时写1和0(_id除外)
|
1 2
| //排序 db.col_name.find().sort({gender:-1}) //参数1为升序,参数-1为降序
|
1 2 3
| //统计个数 db.col_name.find({条件}).count() db.col_name.count({条件})
|
1 2
| //消除重复并返回不重复的结果 db.col_name.distinct('去重字段',{条件})
|
数据类型
1 2 3 4 5 6 7 8 9 10
| Object ID:文档ID String:字符串,有效的utf-8 Boolean:true or false Integer:32位或64位 Double:浮点值 Arrays:数组/列表,多个值存储到一个键 Object:一个值为一个文档,啥意思呢,一个字典中嵌套的另一个字典的意思吧 Null:存储Null值 Timestamp:unix时间戳 Data:当前时间或日期的unix格式
|
- 每个文档都有一个属性,为_id,保证每个文档的唯一性
- 可以自行设计_id插入文档,若没有提供,那么mongodb为每个文档提供l一个独特的_id,类型为object ID
- objectID是一个12字节十六进制数:前四个字节为当前时间戳,接下来三个字节为机器ID,接下来两个字节为Mongodb的服务进程ID,最后三个字节是增量值
聚合
聚合:基于数据处理的聚合管道,每个文档通过一个由多个阶段(stage)组成的管道,可以对每个阶段的管道进行分组、过滤等功能,然后经过一系列的处理,输出相应的结果。
1
| db.col_name.aggregate({管道:{表达式}})
|
常用管道:
1 2 3 4 5 6 7
| $group:将集合中的文档分组 $match:过滤数据,只输出符合条件的文档 $project:修改输入文档的结构,如重命名,增加,删除字段,创建计算结果 $sort:将输入文档排序后输出 $limit:限制聚合管道返回的文档数 $skip:跳过指定数量文档,返回余下的文档 $unwind:将数组类型的字段进行拆分
|
常用表达式:
用于处理文档并输出,操作一般发生在管道之前
1 2 3 4 5 6 7 8 9
| 语法:表达式:'$列名' $sum:计算总和 $sum:1 表示以一倍计数 $avg:计算平均值 $min:获取最小值 $max:获取最大值 $push:在结果文档中插入值到一个数组中 $first:根据资源文档的排序获取第一个文档的数据 $last:根据资源文档的排序获取最后一个文档的数据
|
$group
_id表示分组的依据,使用某个字段的格式为”$字段”
$group对应的字典中有几个键,结果就有几个
1 2 3 4 5 6 7 8 9
| db.stu.aggregate( {$group: { _id:'$gender', counter:{$sum:1}, avg_age:{$avg:"$age"} } } )
|
1 2 3 4 5 6 7 8 9
| db.stu.aggregate( {$group: { _id:null, counter:{$sum:1}, avg_age:{$avg:"$age"} } } )
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| db.stu.aggregate( { $group: { _id:{ country:'$country', city:'$city' } } }, { $project: { country:{$_id.country}, city:{$_id.city}, _id:0 } } )
|
$project
- 统计男生、女生的总人数,并计算平均值,并隐去_id
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| db.stu.aggregate( {$group: { _id:'$gender', counter:{$sum:1}, avg_age:{$avg:"$age"} } }, { { gender:"$_id", _id:0 } } )
|
$match
match是管道命令,能将结果交给后一个管道,但是find不可以
1 2 3 4 5
| db.stu.aggregate( { $macth:{age:{$gt:20}} } )
|
$sort
1
| b.stu.aggregate({$sort:{age:1}})
|
$limit
1
| db.stu.aggregate({$limit:2})
|
$skip
1
| db.stu.aggregate({$skip:2})
|
$unwind
1 2 3 4 5 6 7 8 9
| 现有如下数据: {_id:1,item:"t-shirt",size:['S','M','L']}
db.col_name.aggregate({$unwind:'size'})
结果: {_id:1,item:"t-shirt",size:"S"} {_id:1,item:"t-shirt",size:"M"} {_id:1,item:"t-shirt",size:"L"}
|
索引
提高查询速度
1 2 3 4 5 6 7 8
| for(i=0;i<100000;i++){db.col_name.insert({name:'test'+i,age;i})}
db.col_name.find({name:'test10000'}).explain('executionStats') //explain('executionStats')会输出操作用时 db.col_name.ensureIndex({属性:1}) //1升序 -1降序 db.col_name.ensureIndex({属性:1},{"unique":true}) //建立唯一索引,被索引标记的值不可重复 db.col_name.ensureIndex({属性1:1,属性2:1}) //建立联合索引 db.col_name.getIndexes() //查看索引 db.col_name.dropIndex(索引名称) //删除索引
|
数据备份和恢复
1 2 3 4 5 6
| mongodump -h dbhost -d dbname -o dbdirectory -h:数据所在服务器地址,可指定端口号 -d:数据库名称 -o:备份的数据存放的地址,此目录中放着备份出来的数据
mongodump -h localhost -d test1 -o D:\mongodb_5.1
|
1 2 3 4 5 6
| mongorestore -h dbhost -d dbname --dir dbdirectory -h:同上 -d:需要恢复的数据库实例 --dir:备份数据所在位置
mongorestore -h localhost -d test1 -o D:\mongodb_5.1
|