MongoDB
流行的NoSQL数据库
文档型的NoSQL数据库
名字由来:humongous
https://www.mongodb.org/
https://www.mongodb.com/
web2.0的出现吗,互联网进入大数据时代
关系型数据库固有的缺陷无法处理大数据,于是出现了新型的数据库,这些数据库不使用SQL接口操作数据库,统称为NoSQL数据库
NoSQL数据库分类
-Key-value:memcache、redis
-文档型:Mongodb
-列式:hbase
-图:neo4j
CAP理论
Consistency:所有节点上的数据时刻保持同步
Availability:每个请求都能接收一个相应,无论成功或失败
Partition Tolerance:系统应该能持续提供服务
在一个分布式系统下,不存在任何分布式算法能满足三者
NoSQL数据库的特点
模式自由
逆范式化
多分区存储
动态水平扩展
多副本异步复制
软事务(最终一致性)
MongoDB的特定
面向文档,模式自由
JSON数据格式(BSON)
多级索引
高可用复制集
水平扩展
跨平台、多种语言接口
弱事务类型
大数据量、高并发、弱事物的web2.0互联网应用。
MongoDB的案例
视觉中国、大众点评、淘宝、优酷……
环境
Mongodb
-https://www.mongodb.org/dl/win32/x86_64-2008plus-ssl
Mongovue
-http://www.mongovue.com/
python驱动
-https://pypi.python.org/pypi/pymongo/
python3 -m pip install pymongo
启动:
-mongod --dbpath E:\Program Files\MongoDB\Server\4.0\data --logpath E:\Program Files\MongoDB\Server\4.0\log\mongod.log -logappend --port 27017
-mongod -storageEngine mmapv1 --dbpath E:\Program Files\MongoDB\Server\4.0\data2 --logpath E:\Program Files\MongoDB
\Server\4.0\log\mongod.log --install --serviceName MongoDB --port 27017
-mongod.exe -storageEngine mmapv1 --dbpath E:\Program Files\MongoDB\Server\4.0\data2 --logpath E:\Program Files\MongoDB\Server\4.0\log\mongod.log -logappend --serviceName MongoDB
将mongoDB挂载成windows的服务,开机自动启动
-mongod --dbpath E:\Program Files\MongoDB\Server\4.0\data --logpath --install --serviceName “MongoDB”
常见操作
-mongo # 用于连接mongodb数据库服务器(管理器)mongod --storageEngine mmapv1 --dbpath E:\Program Files\MongoDB\Server\4.0\data
-mongod # 用于开启服务器
-db # 查看当前正在使用的数据库
-use yourdb # use 数据库名 可以用来切换或者创建数据库
-show dbs # 显示数据库列表
-show collections/tables # 显示数据库中的集合列表
-db.dropDatabase() # 删除数据库
db.createCollection(name,options) # 创建集合
name是要创建集合的名称,options(可选参数)是一个文档,用于指定集合的配置
例1:(不限制集合大小)
db.createCollection('stu')
例2:(限制集合大小)
db.createCollection('sub',{capped:true,size:10})
参数capped:默认值为false表示不设置上限,值为true表示设置上限
参数size:当capped值为true时,需要指定此参数,表示上限大小,当文档达到上限时,会将之前的数据覆盖,单位为字节
注意:在MongoDB中不需要创建集合,当插入一些文档时,MongoDB会自动创建集合。
命令行操作演示:
常见操作(CRUD)
-db.collection.insert({“键名1”:“值1”,“键名2”:“值2”,“键名3”:“值3”……}) # collection 集合的名字
注意:如果集合名存在则写入新数据,不存在就创建集合
-db.collection.find() # 查看数据
-db.collection.find().pretty() # 数据以键值对显示格式化
-db.collection.remove({}) # 删除所有数据
-db.collection.remove({“键名”:“值”}) # 删除一条记录
-db.collection.drop() # 清空记录
-db.collection.update({查询条件},{修改的目标}) # 修改数据
修改需要注意:db.test.students.update((name:‘bajie’),(name:‘zhubajie’)) 会将name:'bajie’的其余属性值删除
正确的修改方法为:db.test.students.update({name:‘bajie’},{$set:{name:‘zhubajie’}})
https://docs.mongodb.com/manual/introduction/
插入
-insert_one(doc)
-insert_many(doc,ordered=True/False)
查询
-find(filter) db.collection.find("score":{"$gt":0})
Operator Meaning Example SQL Equeivalent
$gt Greater Than "score":{"$gt":0} >
$lt Less Than "score":{"$lt":0} <
$gte Greater Than or Equal "score":{"$gte":0} >=
$lte Less Than or Equal "score":{"$lte":0} <=
$all Array Must Contain All "skills":{"$all":["mongodb","python"]} N/A
$exists Property Must Exist "email":{"$exists":True} N/A
$mod Modulo X Equals Y "seconds":{"$mod":[60,0]} MOD()
$ne Not Equals "seconds":{"$ne":60} !=
$in In "skills":{"$in":["c","c++"]} IN
$nin Not In "skills":{"$nin":["php","ruby","perl"]} NOT IN
$nor Nor "$nor":[{"language":"english"},{"country":"usa"}] N/A
$or Or "$or":[{"language":"english"},{"country":"usa"}] OR
$size Array Must Be Of Size "skills":{"$size":3} N/A
更新
-update_one(filter,update,upsert=True/False)
-update_many(filter,update,upset=True/False)
Modifier Meaning Example
$inc Atomic Increment "$inc":{"score":1}
$set Set Property Value "$set":{"username":"niall"}
$unset Unset (delete) Property "$unset":{"username":1}
$push Atomic Array Append(atom) "$push":{"emails":"foo@example.com"}
$pushAll Atomic Array Append(list) "$pushall":{"emails":["foo@example.com","foo2@example.com"]}
$addToSet Atomic Append-If-Not-Present "$addToSet":{"emails":"foo@example.com"}
$pop Atomic Array Tail Remove "$pop":{"emails":1}
$pull Atomic Conditional Array Item Removal "$pull":{"emails":"foo@example.com"}
$pullAll Atomic Array Multi Item Removal "$pullAll":{"emails":["foo@example.com","foo2@example.com"]}
$rename Atomic Property Rename "$rename":{"emails":"old_emails"}
替换
-replace_one(filter,replacement,upsert=False)
删除
-delete_one(filter)
-delete_many(filter)
排序
db.collection.find().sort({"key1":-1,"key2":1})
这里的1代表升序,-1代表降序
示例:db.collection.find({}).sort({"age":-1})
SQL: select * from singer order by age asc;
MongoDB使用ensureIndex()方法来创建索引
db.COLLECTION_NAME.ensureIndex({KEY:1})
限制输出:
db.collection.find().limit(n) # 控制返回结果数量,如果参数是0,则没有约束,limit()将不起作用
示例:db.collection.find({}).sort({"age":1}).limit(3);
SQL: select * from singer order by age asc limit 3;
db.collection.find().skip(n) # 控制返回结果跳过多少数量,如果参数是0,则当做没有约束,skip()将不起作用,或者说跳过了0条
示例:db.collection.find({}).sort({"age":1}).skip(3).limit(2); # 找出年龄除最小的三个以外的2个人(跳过最小的三条,输出2两条)
SQL: select * from singer order by age asc limit 3,2;
db.collection.find().limit(5).skip(5) # 可用来做分页,跳过五条数据,再取5条数据
db.collection.find().count() # count()返回结果集的条数
db.collection.find().limit(5).skip(5).count(true) # 在加入skip和limit这两个操作时,要获得实际返回的结果数,需要一个参数true,否则返回的是符合查询条件的结果数
查询同时更新
-find_one_and_replace
-find_one_and_delete
-find_one_and_update
find_one_and_update(filter,update,projection=None,sort=None,return_document=ReturnDocument.BEFORE, **kwargs)
聚合 aggregate:主要用于计算数据,类似于sql中的sum()、avg()
语法: db.集合名称.aggregate([{管道:{表达式}}])
管道:管道一般用于将当前命令的输出结果作为下一个命令的输入,在mongodb中,管道具有同样的作用,文档处理完毕后,通过管道进行下一次处理
表达式:处理输入文档并输出
语法:表达式:'$列名'
常用管道:
$group :将集合中的文档分组,可用于统计结果
$match :过滤数据,只输出符合条件的文档
$project :修改输入文档的结构,如重命名、增加、删除字段、创建计算结果
$sort :将输入文档排序后输出
$limit :限制聚合管道返回的文档数
$skip :跳过指定数量的文档,并返回余下的文档
$unwind :将数组类型的字段进行拆分
常用表达式:
$sum :计算总和,$sum:1 同count表示计数
$avg :计算平均数
$min :获取最小值
$max :获取最大值
$push :在结果文档中插入值到一个数组中
$first :根据资源文档的排序获取第一个文档数据
$last :根据资源文档的排序获取最后一个文档的数据
核心语法:
db.集合名.aggregate([
{管道1:{表达式}},
{管道2:{表达式}},
{管道3:{表达式}},
]);
$limit 限制输出示例:
db.集合名.aggregate([{$limit:限制输出的条数}]);
$group 分组:
语法 : db.集合.aggregate([{$group:{_id:'$字段',别名:{$表达式:'$字段'}}}])
//select * from student group by 字段;
示例 : 统计男生、女生的总人数
db.singer.aggregate({
$group:{
_id:'$sex',
count:{$sum:1}
}
});
根据性别统计所有同学的名单
db.singer.aggregate({
$group:{
_id:'$sex',
人数:{$sum:1},
名单:{$push:'$name'} //相当于拼接字段 group_concat()
}
})
求学生总人数、平均年龄
db.singer.aggregate({
$group:{
_id:null,
总人数:{$sum:1},
平均年龄:{$avg:'$age'}
}
})
$sum 计算总和(统计个数:$sum:1 、累加:$sum:'$字段名'
示例:
db.singer.aggregate({
$group:{
_id:null,
总人数:{$sum:1}, // 统计总个数
总年龄{$sum:'$age'}, //累加
平均年龄:{$avg:'$age'},//平均值
最大年龄:{$max:'$age'},//最大值
最小年龄:{$min:'$age'},//最小值
名单:{$push:'$name'}, //将同组的名字进行拼接
小组第一:{$first:'$name'},
小组最后:{$last:'$name'}
}
});
$match 管道,匹配条件
db.集合名.aggregate({
$match:{"键名":{$gt:30}}
})
示例:找出年龄大于50的歌手
db.singer.aggregate(
{$match:{
"age":{$gt:50}
}
}
)
找出年龄大于40的歌手进行性别分组统计
db.singer.aggregate([
{$match:{
"age":{$gt:40}
}
},
{$group:{
_id:'$sex',
总人数:{$sum:1}
}
}
])
$project 管道,限定输出字段
相当于SQL:select name,age from student;
db.集合名.aggregate({
$project:{
name:1 | 0 //1表示显示,0表示不显示
}
});
示例:找出年龄大于50的歌手,只显示姓名和年龄
db.singer.aggregate([
{$match:{
"age":{$gt:50}
}
},
{$project:{
_id:1,
name:1,
age:1}
}
}
])
$sort 排序管道
db.集合名.aggregate({
$sort:{
“键名”:1 | -1 //1表示显示,0表示不显示
}
});
示例:找出年龄大于50的歌手,只显示姓名和年龄,按年龄排序,限制输出前三条
db.singer.aggregate([
{$match:{"age":{$gt:50}}},
{$project:{_id:1,name:1,age:1}}},
{$sort:{'age':1}}, //按年龄从小到大进行排序
{$skip:2}, //跳过3条
{$limit:3} //输出3条
])
$skip 管道,跳过n条
db.集合名.aggregate({
$skip:n
});
$unwind 管道,将数组字段进行拆分
db.集合名.aggregate({
$unwind:'键名'
});
示例:拆分works字段
db.singer.aggregate([
{$match:{"age":{$gt:50}}},
{$unwind:'$works'}
]);
聚合操作
聚合操作等价于关系数据库的分组汇总统计,比如分组求和、最大值、最小值
SELECT cust_id, ord_date, SUM(price) AS total
FROM orders
GROUP BY cust_id, ord_date
HAVING total >250
聚合管道
如同linux管道
管道操作符
表达式操作符
例:db.orders.aggregate([ # Collection
{$match:{status:"A"}}, # $match stage
{$group:{_id:"$cust_id",total:{$sum:"$amount"}}} # $group stage
])
管道阶段:前一阶段的结果是后一阶段的开始
collection.aggregate([{stage1},{stage2},...])
管道操作符与SQL语句对照表:
SQL Terms,Functions,and Concepts MongoDB Aggregation Operators
WHERE $match
GROUP BY $group
HAVING $match
SELECT $project
ORDER BY $sort
LIMIT $limit
SUM() $sum
COUNT() $sum
1、以无管理身份进入数据库
2、设置管理员账号
a、新建数据库 admin
use admin
b、创建用户名和密码
db.createUser({user:“admin”,pwd:“password”,roles:[“root”]})
3、验证密码
db.auth(‘admin’,‘password’)
4、重新挂mongodb服务
卸载之前的服务
sc delete mongodb
挂起需要验证的服务器
mongod --dbpath E:\Program Files\MongoDB\Server\4.0\data --logpath E:\Program Files\MongoDB\Server\4.0\log\mongod.log --auth
–auth 是指身份验证
启动服务
net start mongodb
5、测试账户
show dbs; //无法访问,需要身份验证
db.auth(‘root’,‘root’)
6、为其它数据库添加用户
db.createUser({user:“itsource”,pwd:“123”,roles:[{role:“dbOwner”,db:“itsource”}]});