0%

mongodb学习(1)

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}})

范围运算符:

  • $in $nin
1
db.stu.find({age:{$in:[18,28,38]}})

逻辑运算符:

  • and:,
  • or:$or
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不可以

  • 查询年龄大于20的学生
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