Ubuntu下安装MongoDB:
sudo apt-get install mongodb
SQL:(MySQL、Oracle、SQL Server、DB2)
- 高度事务性的场景,银行、会计、贸易、库管,需要大量原子性操作
- 数据存储要求有规范的多表结构设计,预定义明确的字段
- 数据价值高,对安全和稳定性要求高
- 需要持久化存储的 “冷数据”(不需要经常读写的数据)
- 需要通过SQL语句支持的存储场景
NoSQL:
Redis key:value(string、list、hash、set、zset)
MongoDB {key1 : value1, key2 : value2}, {key1 : value1}
- 高度伸缩性场景,更容易扩展,支持集群
- 灵活的数据结构,不需要事先设计数据库数据表字段,即用即存,社交网络、热点资讯
- 处理 “热数据”(需要经常读写的数据),NoSQL大部分操作都是和内存交互,读写效率极高
- 不需要SQL语句支持,学习成本低
MongoDB 服务和客户端 命令:
- 开启数据库服务: sudo mongod
- 开始shell客户端: mongo
- 关闭 shell客户端 和 数据库服务, ctrl + c
- 在admin数据库下,通过 db.shutdownServer() 来关闭服务
MongoDB数据库操作的常用命令:
- 表示当前所在的数据库
db
- 查看所有的数据库
show dbs
- 切换到指定数据库
use mydb
- 查看当前数据库下的所有集合(相当于SQL的表)
show collections
- 查看当前数据库下 指定集合 的所有文档(相当于 每一条数据)
db.mycollection.find()
- 删除当前数据库的 指定集合
db.mycollection.drop()
- 删库
db.dropDatabase()
MongoDB 的 用户权限:
-
第一次进入到MongoDB没有用户,所以是root权限,
需要先创建一个有root权限的用户:use admin
db.createUser() dbcreateUser({user:“python”, pwd: “xiao”,roles:[“root”]})在使用这个用户创建其他用户
db.auth()
-
第二次开启MongoDB服务,要通过 --auth 启动用户权限模式,才可以让用户权限生效。
use admin
认证登录到python用户
db.auth() db.auth(“python”,“xiao”)
查看当前认证登录的用户信息
show users
查看当前数据库下所有的用户信息:
db.system.users.find()
删除python用户
db.dropUser(“python”)
------------------ MongoDB 增加数据 : insert
- insert() 接收一个文档 参数
db.stu.insert({ “_id” : 1, “name” : “诸葛亮”, “age” : 40, “hometown” : “蜀” })
- 构建空文档,添加字段,再写入
data = {}
data._id = 2
data.name = “刘备”
data.age = 48
data.hometown = “蜀”
db.stu.insert(data)
------------------ MongoDB 删除数据 : remove
- 删除所有符合条件的文档,也可以同时指定多个条件
db.stu.remove({“age” : 18})
db.stu.remove({“age” : 18, “hometown” : “蜀”})
- 只删除第一个符合条件的文档,通过添加第二个参数 {justOne : true}
db.stu.remove({“age” : 18}, {justOne : true})
- 不添加任何条件,则删除全部文档
db.stu.remove()
db.stu.drop()
------------------ MongoDB 修改数据 : update
update() 至少需要两个参数,第一个参数为匹配条件,第二个参数为修改内容(可添加第三个参数表示是否全部匹配)
- 将第一个符合条件的文档,替换为 第二个参数对应的文档(整个文档替换)
将第一个 age 为48的文档,替换为 {age : 49}, 但是 _id 保持不变
db.stu.update({age : 48}, {age : 49})
- 如果只修改特定字段,通过 $set 修饰符处理 (局部文档修改)
将第一个age为48的文档,修改age为49,其他字段保持不变
db.stu.update({age : 48}, {$set : {age : 49}})
将第一个age为48的文档,修改age为49,并添加gender字段,其他字段保持不变
db.stu.update({age : 48}, {$set : {age : 49, gender : true}})
- 默认只处理第一条符合条件的文档,通过第三个参数 {multi : true} 表示全部处理 (修改所有文档)
将所有age为48的文档,修改age为49,其他字典不变
db.stu.update({age : 48}, {$set : {age : 49}}, {multi : true})
------------------ MongoDB 新增+修改数据 : save
save() 需要一个文档参数,根据文档的 _id 来处理,
- 如果_id 存在,则修改数据,
db.stu.save({_id : 1, name : “马超”, age : 36, hometown : “蜀”})
- 如果_id 不存在则新增
db.stu.save({_id : 5, name : “黄忠”, age : 56, hometown : “蜀”})
insert() 如果_id存在则报错, save则修改数据
update() 修改数据可以指定字段修改,save则全部替换。
安装: pip install pymongo
import pymongo
client = pymongo.MongoClient(host='127.0.0.1', port=27017)
client.test.stu.insert({})
client.test.stu.insert([{}, {}, {}])
client.test.stu.find({})
------------------ MongoDB 查询数据 : find()
- find() 和 findOne()
find() 查询所有符合条件的文档
findOne() 查询第一个符合条件的文档
db.stu.find({age : 18, hometown : “桃花岛”})
db.stu.findOne({age : 18})
- 比较运算符(通常用于比较数据,如果是字符串则比较字节码)
默认是 等于
$gt 大于
$gte 大于等于
$lt 小于
$lte 小于等于
$ne 不等于
db.stu.find({age : 18})
db.stu.find({age : {$gt : 18}})
- 逻辑运算符(用于表示多个 独立条件的逻辑关系)
$and 和 $or 用来修饰多个条件的 数组
db.stu.find({age : 18, hometown : “桃花岛”})
db.stu.find( {$or : [{age : 18}, {hometown : “桃花岛”}]})
db.stu.find( {$or : [ {$and : [{age : 18}, {hometown : "桃花岛"}]}, {gender : true}]})
- 范围运算符
$in 在
$nin 不在
#查找age 不是 16 18 20 的文档信息
db.stu.find({age : {$nin : [16, 18, 20]}})
查找age 是 16 18 20 , 同时 hometown 是 蒙古 或 大理
db.stu.find({age : {$in : [16, 18, 20]}, hometown : {$in : ["蒙古", "大理"]}})
- 正则表达式
按正则表达式匹配文档, / / 内写的正则表达式匹配文本
db.stu.find({name : /^黄/})
通过 $regex修饰 启动正则匹配文本
db.stu.find({name : {$regex : “^黄”}})
通过 $options 启动正则修饰 ,如 $i 表示 忽略英文大小写
db.stu.find({name : {$regex : “^Big”, o p t i o n s : " options : " options:"i"}})
- 自定义函数查询 $where (了解)
db.stu.find({$where : function() { return this.age != 20 })
----------- 对find() 查询结果的处理:
- limit() 和 skip()
limit() 表示开始显示多少个
db.stu.find().limit(3)
skip() 表示跳过多少个开始显示
db.stu.find().skip(3)
如果 limit()和 skip()组合使用,执行结果一定是先 执行 skip() 再执行 limit()
db.stu.find().skip(3).limit(3)
- 投影显示
当find() 添加第二个参数,表示启用投影,可以指定字段显示
(1). 通过 1 和 true 指定显示字段,默认其他字段不显示
db.stu.find({}, {name : 1, age : true})
(2). 通过 0 和 false 指定不显示字段,默认其他字段显示
db.stu.find({}, {name : 0, hometown: false})
默认情况下,_id 是一定显示的,除非手动指定不显示
db.stu.find({}, {name : 0, hometown: false, _id : 0})
- sort() 排序
sort() 指定任意字段排序,1 为升序, -1 为降序,通常对数字排序,如果是字符串则按首字母的ascii值排序
(1). 单个排序
#按年龄进行升序排序
db.stu.find().sort({age : 1})
(2) 多个排序:先执行第一个排序,如果出现重复值,再按第二个排序处理
先按age进行升序排序,如果有age相同的文档,再按 gender 降序排序
db.stu.find().sort({age : 1, gender : -1})
- count() 统计个数
(1). 在find()后添加 count() 统计文档个数
db.stu.find({age : {$gte : 18}}).count()
(2). 代替find() 直接统计个数
db.stu.count()
db.stu.count({age : {$gte : 18}})
- distinct() 去重显示
-1. 直接显示指定字段去重后的 数组
db.stu.distinct(“hometown”)
-2. 配合查询条件,显示符合条件的文档中 指定字段的值
db.stu.distinct(“hometown”, {age : {$gte : 18}})
数据分析:统计+概率
----------- MongoDB 的聚合运算
aggregate([ {$match}, {$group}, {} ])
- $group 分组统计
对所有文档按 gender进行分组,再分别统计每组 age 的总和
-1 $sum 求和统计计算
-2 $sum : 1 统计个数
-3 $avg : 统计平均数
-4 $max 和 $min 求最大值和最小值
-5 $first 和 $last 求第一个和最后一个
db.stu.aggregate([
{
group : {
# 表示分组依据
_id : "$gender",
# 统计 文档个数
count : {$sum : 1},
# 统计 age 总和
sum_age : {$sum : "$age"},
# 统计 age 平均数
avg_age : {$avg : "$age"},
# 统计 age 最大值
max_age : {$max : "$age"},
# 统计 age 最小值
min_age : {$min : "$age"},
# 统计 第一个 name
first_name : {$first : "$name"},
# 统计 最后一个 name
last_name : {$last : "$name"},
# 统计所有hometown 并保存在数组中
all_hometown : {$push : "$hometown"}
}
},
{ }
])
- match 文档条件匹配(通过配合$group做预处理,将符合条件的文档再通过group分组统计)
db.stu.aggregate([
# 先找出所有 hometown 不为 汉 文档
{$match : {"hometown" : {$nin : ["汉"]}}},
# 在match匹配结果里,按 gender进行分组,再统计所有文档的 name
{$group : {_id : "$gender", all_name : {$push : "$name"}}}
])
- $project 投影显示
db.stu.aggregate([ {$group : {_id : "$hometown", max_age : {$max : "$age"}, min_age : {$min : "$age"}}}, {$project : {_id : 0, max_age : 1}}])
- $sort 排序处理
db.stu.aggregate([
{$group : {_id : "$hometown", max_age : {$max : "$age"}, min_age : {$min : "$age"}}},
{$sort : {min_age : 1, max_age : -1}}
])
- $limit 和 $skip
db.stu.aggregate([ {$group : {_id : "$hometown", max_age : {$max : "$age"}, min_age : {$min : "$age"}}}, {$sort : {min_age : 1, max_age : -1}}, {$limit : 3}, {$skip : 2}])
{ “_id” : “蒙古”, “max_age” : 20, “min_age” : 18 }
db.stu.aggregate([ {$group : {_id : "$hometown", max_age : {$max : "$age"}, min_age : {$min : "$age"}}}, {$sort : {min_age : 1, max_age : -1}}, {$skip : 2}, {$limit : 3}])
Python代码用法:
stu.aggregate([ {"$group" : {"_id" : "$hometown", "max_age" : {"$max" : "$age"}, "min_age" : {"$min" : "$age"}}}, {"$sort" : {"min_age" : 1, "max_age" : -1}}, {"$skip" : 2}, {"$limit" : 3}])
- $unwind
db.stu.aggregate([ {$group : {_id : "$hometown", all_name : {$push : "$name"}}}, {$unwind : "$all_name"} ])
---------- MongoDB的索引操作 (索引是在集合为单位)
for(i=0;i<100000;i++)
{
db.data.insert({_id : i, name : “name”+i, age : i+10})
}
- 查看find() 执行状态
db.data.find({_id : 10240}).explain(“executionStats”)
- 查看索引,每个索引对应 一个name 索引名
db.data.getIndexes()
- 创建索引
db.data.ensureIndex({name : 1})
- 删除索引 (根据索引名删除,通过getIndexes()查看)
db.data.dropIndex(“name_1”)
------------ MongoDB 的集合数据 导出 和 导入 (以集合为单位)
- 将指定数据库 指定集合 的数据 导出为 json 或 csv
默认输出为json
sudo mongoexport -d test -c stu -o ./stu.json
通过–type指定导出为csv文件,并通过 -f 添加字段
sudo mongoexport -d test -c stu -o ./stu.csv --type csv -f “_id,name,age,hometown,gender”
- 将json文件导入到 mongodb 指定的数据库 指定的集合里
sudo mongoimport -d test -c stu --file ./stu.json
-------------- MongoDB 数据库的 备份和恢复(以数据库为单位)
- 数据库的备份
将 -h 指定的MongoDB服务器 的 -d 指定的数据库,备份到-o指定的目录中
sudo mongodump -h 192.168.37.80 -d test -o ./mongo_data/
- 数据库的恢复
将 --dir 指定的数据库目录里的文件,恢复到 -h 指定的MongoDB服务器 的 -d指定的数据库里
sudo mongorestore -h 192.168.37.90 -d test --dir ./mongo_data/test