一、简介
1. 介绍
MongoDB 旨在为WEB应用提供可扩展的高性能数据存储解决方案。
MongoDB 将数据存储为一个文档,数据结构由键值(key=>value)对组成。MongoDB 文档类似于 JSON 对象。字段值可以包含其他文档,数组及文档数组。
对应关系
MySQL MongoDB
DB DB
table Collections
row Documents
column Field
2. Redis和MongoDB的区别(面试受用)
redis用来存储一些热数据,量也不大,但是操作很频繁;MongoDB存储数据目前是百万级的数据,将来会有千万级、亿级就Redis和MongoDB来说,大家一般称之为Redis缓存、MongoDB数据库。Redis主要把数据存储在内存中,其“缓存”的性质远大于其“数据存储“的性质,其中数据的增删改查也只是像变量操作一样简单;MongoDB却是一个“存储数据”的系统,增删改查可以添加很多条件,就像SQL数据库一样灵活,这一点在面试的时候很受用。
应用场景
mongodb 海量数据的访问效率提升
redis 较小数据量的性能及运算
二、安装
mongodb和noSQLBooster网盘连接:
链接:https://pan.baidu.com/s/1mRKSlD7VUcycYIGKmQ6sAQ
提取码:f9lt
下载官网
https://www.mongodb.com/download-center/community windows安装
pycharm连接
linux安装
三、SQL命令
传统的关系数据库(如mysql)一般由数据库(database)、表(table)、记录(record)三个层次概念组成,
MongoDB是由数据库(database)、集合(collection)、文档对象(document)三个层次组成。
SQL命令转载于:
数据类型
String: 字符串,必须是utf-8
Boolean:布尔值,true 或者 false (这里有坑哦~在我们大Python中 True False 首字母大写)
Integer:整数 (Int32 Int64 你们就知道有个Int就行了,一般我们用Int32)
Double:浮点数 (没有float类型,所有小数都是Double)
Arrays:数组或者列表,多个值存储到一个键 (list哦,大Python中的List哦)
Object:如果你学过Python的话,那么这个概念特别好理解,就是Python中的字典,这个数据类型就是字典
Null:空数据类型 , 一个特殊的概念,None Null
Timestamp:时间戳
Date:存储当前日期或时间unix时间格式 (我们一般不用这个Date类型,时间戳可以秒杀一切时间类型)
看着挺多的,但是真要是用的话,没那么复杂,很简单的哦
1. 数据库操作
1、查看mongo帮助文档
mongo -h
2、登陆
mongo -umiaobt -p --authenticationDatabase
mongo -umiaobt -p331sharp --authenticationDatabase
以下操作需要登陆数据库才能操作
// 库操作
3、查询所有库
show dbs;
4、查询库中的连接
show collecitons;
5、创建数据库/切换数据库
use test1;
1
如果没有test1这个库,会创建
6、删除数据库
db.dropDatabase();
1
7、获取数据库名称
db.getName();
1
8、获取数据库状态
db.stats();
1
9、当前db版本
db.version();
1
10、查看当前db的链接机器地址
db.getMongo();
1
11、从指定主机上克隆数据库
db.cloneDatabase("127.0.0.1");
1
12、从指定的机器上复制指定数据库数据到某个数据库
db.copyDatabase("yhb", "test1", "127.0.0.1");
1
13、修复数据库
db.repairDatabase();
1
2. MongoDB集合操作
1、创建一个聚集集合(table)
//指定数据库大小size,最大存放100个文档,满了,就会mongodb 会删除旧文档。
human时集合名
db.createCollection("human",{"size":1024,capped:true,max:100});
db.createCollection("people");
1
2
3
2、查看集合状态
db.people.stats();
1
3、获取指定集合
db.getCollection("human");
1
4、获取当前db中的所有集合
db.getCollectionNames();
1
和show collections类似
5、显示当前db所有聚集索引的状态
db.printCollectionStats();
1
6、一般情况下创建集合是直接在collections中插入数据,然后会自动保存表
> db.perple.insert({name:"tian",age:2})
WriteResult({ "nInserted" : 1 })
> db.perple.find()
{ "_id" : ObjectId("5eb794653d6a9bd230be0232"), "name" : "tian", "age" : 2 }
7、删除表和查看所有表
> db.perple.drop()
true
>
> show tables;
user
3. MongoBD用户操作
1、添加一个用户
db.createUser({user:"zs",pwd:"111",roles:["read"]})
1
添加用户、设置密码、是否只读
2、数据库认证、安全模式
db.auth(“zs”, “111”);
3、显示当前所有用户,角色
show people;
show roles;
4、删除用户
db.removeUser("zs");
1
4.集合数据操作
1、添加
添加一条数据:
db.people.insert({name: 'zhangsan', age: 18, sex: true});
1
添加多条数据:
db.people.insertMany([{name: 'zhangsan', age: 18, sex: true},{name: 'lisi', age: 28, sex: false}]);
添加的数据的数据列,没有固定,根据添加的数据为准
2、修改
db.people.update({age: 18}, {$set: {name: 'changeName'}}, false, true);
相当于:update people set name = 'changeName' where age = 18;
db.people.update({name: 'zhangs'}, {$inc: {age: 12}}, false, true);
相当于:update people set age = age + 12 where name = 'zhangs';
db.people.update({name: 'zhangs'}, {$inc: {age: 12}, $set: {name: 'hoho'}}, false, true);
相当于:update people set age = age + 12, name = 'hoho' where name = 'zhangs';
1
2
3
4
5
6
3、删除
db.people.remove({age: 12});
5. 集合查询
1、查询所有记录
引用块内容
db.people.find();
相当于:select* from people;
2、查询去掉后的当前聚集集合中的某列的重复数据
db.people.distinct("name");
相当于:select distict name from people;
3、查询age = 18的记录
db.people.find({"age": 18});
相当于: select * from people where age = 18;
4、查询age > 18的记录
db.people.find({age: {$gt: 18}});
相当于:select * from people where age >18;
5、查询age < 18的记录
db.people.find({age: {$lt: 18}});
相当于:select * from people where age <18;
6、查询age >= 18的记录
db.people.find({age: {$gte: 18}});
相当于:select * from people where age >= 18;
1
2
7、查询age <= 18的记录
db.people.find({age: {$lte: 18}});
1
8、查询age >= 23 并且 age <= 26
db.people.find({age: {$gte: 23, $lte: 26}});
1
9、查询name中包含 mongo的数据
db.people.find({name: /mongo/});
相当于:select * from people where name like '%mongo%';
1
2
10、查询name中以mongo开头的
db.people.find({name: /^mongo/});
1
相当于:select * from people where name like ‘mongo%’;
11、查询指定列name、age数据
db.people.find({}, {name: 1, age: 1});
1
相当于:select name, age from people;
当然name也可以用true或false,当用ture的情况下河name:1效果一样,如果用false就是排除name,显示name以外的列信息。
12、查询指定列name、age数据, age > 18
db.people.find({age: {$gt: 18}}, {name: 1, age: 1});
相当于:select name, age from people where age >18;
1
2
13、按照年龄排序
升序:db.people.find().sort({age: 1});
降序:db.people.find().sort({age: -1});
1
2
14、查询name = zhangsan, age = 18的数据
db.people.find({name: 'zhangsan', age: 18});
相当于:select * from people where name = 'zhangsan' and age = '18';
1
2
15、查询前5条数据
db.people.find().limit(5);
相当于:select * from people Limit 5;
1
2
16、查询10条以后的数据
db.people.find().skip(10);
相当于:select * from people where id not in (select id from people limit 10);
1
2
17、查询在5-10之间的数据
db.people.find().limit(10).skip(5);
可用于分页,limit是pageSize,skip是第几页*pageSize
1
2
18、or与查询
db.people.find({$or: [{age: 18}, {age: 18}]});
相当于:select * from people where age = 18 or age = 18;
1
2
19、查询第一条数据
db.people.findOne();
相当于:select * from people limit 1;
db.people.find().limit(1);
1
2
3
20、查询某个结果集的记录条数
db.people.find({age: {$gte: 18}}).count();
相当于:select count(*) from people where age >= 20;
1
2
21、求总数
db.people.find({sex: {$exists: true}}).count();
相当于:select count(sex) from people;
6. 索引
1、创建索引
use testdb
db.test1.ensureIndex({"name":1,"age":-1})
ensureIndex方法参数中,数字1表示升序,-1表示降序。
2、查询索引
db.test1.getIndexes()
3、删除索引
删除所有的索引:
db.test1.dropIndexes()
根据索引名称进行删除
db.test1.dropIndex("name_1")
4、重建索引
db.test1.reIndex()
7、高级用法$,sort,limit,skip
1.$修改器 :
$set 简单粗暴 {name:value} dict[“name”]=value
$unset 简单粗暴的删除字段 {$unset:{name:1}} del dict["name"]
db.user_info.updateOne({age:200},{$unset:{age:1}})
$inc 引用增加
db.user_info.updateMany({},{$inc:{age:1}})
array操作
$push 在array中追加一个新的元素 [].append(item)
db.user_info.updateOne({name:"200wansui"},{$push:{hobby:10}})
$pull 在array中删除一个的元素 [].remove(item) [].pop(-1)
db.user_info.updateOne({name:"200wansui"},{$pull:{hobby:0}})
$pop 不含索引 -1 从前往后 1 从后往前
db.user_info.updateOne({name:"200wansui"},{$pop:{hobby:1}})
2.$ 字符
db.user_info.updateOne({hobby:6},{$set:{"hobby.$":"六"}})
保存符合索引条件数据的下标
3.Object 字典操作
db.user_info.updateOne({name:"200wansui"},{$inc:{"info.tizhong":-5}})
db.user_info.updateOne({name:"200wansui"},{$set:{"info.long":12.5}})
4.array + Object
db.user_info.updateOne({"hobby.shengao":150},{$set:{"hobby.$.long":14}})
5.limit
db.user_info.find({}).limit(5)
选取数据从当前位置选择5个
6.skip 跳过
db.user_info.find({}).skip(2)
从0开始跳过2条数据为当前位置
7.sort
db.user_info.find({}).sort({ id:-1 })
根据ID进行排序 -1倒叙 1正序
8.limit+skip+sort
优先级最高的是 sort
其次优先为 skip
最低优先级 limit
db.user_info.find({}).limit(5).skip(10)
db.user_info.find({}).limit(c).skip((p-1)*c)
db.user_info.find({}).limit(5).skip(5).sort({ id:-1 })
四、pythonORM控制MongoDB
pythonORM控制MongoDB转载于
1. MongoEngine介绍:
MongoEngine是一个对象文档映射器(ODM),相当于一个基于SQL的对象关系映射器(ORM)
pymongo来操作MongoDB数据库,但是直接把对于数据库的操作代码都写在脚本中,这会让应用的代码耦合性太强,而且不利于代码的优化管理
一般应用都是使用MVC框架来设计的,为了更好地维持MVC结构,需要把数据库操作部分作为model抽离出来,这就需要借助MongoEngine,MongoEngine提供的抽象是基于类的,创建的所有模型都是类
安装
pip install mongoengine
2. MongoEngine使用
- 使用时先声明一个继承自MongoEngine.Document的类
在类中声明一些属性,相当于创建一个用来保存数据的数据结构,即数据已类似数据结构的形式存入数据库中,通常把这样的一些类都存放在一个脚本中,作为应用的Model模块
from mongoengine import *
connect('mydb', host='localhost', port=27017)
import datetime
class Users(Document):
name = StringField(required=True, max_length=200)
age = IntField(required=True)
users = Users.objects.all() #返回所有的文档对象列表
for u in users:
print("name:",u.name,",age:",u.age)
- 保存文档
required:设置必须;
default:如果没有其他值给出使用指定的默认值
unique:确保集合中没有其他document有此字段的值相同
choices:确保该字段的值等于数组中的给定值之一
from mongoengine import *
connect('mydb', host='localhost', port=27017)
import datetime
class Users(Document):
name = StringField(required=True, max_length=200)
age = IntField(required=True)
user1 = Users(
name='jack',
age= 21
)
user1.save()
print(user1.name)
user1.name = 'jack2'
user1.save()
print(user1.name)
- 查询10=<年龄<30的,按姓名排列
from mongoengine import *
connect('mydb', host='localhost', port=27017)
import datetime
class Users(Document):
name = StringField(required=True, max_length=200)
age = IntField(required=True)
user_search = Users.objects(age__gte=10, age__lt=33).order_by('name')
for u in user_search:
print("name:",u.name,",age:",u.age)
查询10=<年龄<30的,按姓名倒序
from mongoengine import *
connect('mydb', host='localhost', port=27017)
import datetime
class Users(Document):
name = StringField(required=True, max_length=200)
age = IntField(required=True)
user_search = Users.objects(age__gte=10, age__lt=33).order_by('-name')
for u in user_search:
print("name:",u.name,",age:",u.age)
查询name=jack2
from mongoengine import *
connect('mydb', host='localhost', port=27017)
import datetime
class Users(Document):
name = StringField(required=True, max_length=200)
age = IntField(required=True)
tmp = Users.objects(name="jack2")
for u in tmp:
print("name:",u.name,",age:",u.age)
4.修改name=jack2 的age加1
from mongoengine import *
connect('mydb', host='localhost', port=27017)
import datetime
class Users(Document):
name = StringField(required=True, max_length=200)
age = IntField(required=True)
tmp = Users.objects(name="jack3").update(inc__age=1)
tmp = Users.objects(name="jack3")
for u in tmp:
print("name:",u.name,",age:",u.age)
修改name=jack的age设为66
from mongoengine import *
connect('mydb', host='localhost', port=27017)
import datetime
class Users(Document):
name = StringField(required=True, max_length=200)
age = IntField(required=True)
tmp = Users.objects(name="jack").update(set__age=66)
tmp = Users.objects(name="jack")
for u in tmp:
print("name:",u.name,",age:",u.age)
3. MongoEngine高级查询
例如有时候你需要将约束条件进行与,或的操作。你可以使用mongoengine提供的 Q 类来实现,一个 Q 类代表了一个查询的一部分,里面的参数设置与你查询document的时候相同。建立一个复杂查询的时候,你需要用 & 或 | 操作符将 Q 对象连结起来,例子如下:
Post.objects(Q(name=“jack”) | Q(age=66))
查询相关操作符
ne – 不等于
lt – 小于
lte – 小于等于
gt – 大于
gte – 大于等于
not – 使其检查的反面,需要使用在其他操作符之前(e.g. Q(age__not__mod=5))
in – 值在list里面
nin – 值不在list里面
mod – value % x == y
all – list里面所有的值
size – 这个array的大小
exists – 存在这个值
#一下操作符在需要进行正则检查的时候是比较快捷的方法:
exact – 字符串型字段完全匹配这个值
iexact – 字符串型字段完全匹配这个值(大小写敏感)
contains – 字符串字段包含这个值
icontains –字符串字段包含这个值(大小写敏感)
startswith – 字符串字段由这个值开头
istartswith –字符串字段由这个值开头(大小写敏感)
endswith – 字符串字段由这个值结尾
iendswith –字符串字段由这个值结尾(大小写敏感)
match – 使你可以使用一整个document与数组进行匹配查询list
五、python 控制MongoDB
转载于https://www.jianshu.com/p/08c384bef2e4
1 使用Python连接MongoDB
# 建立客户端连接的三种方法
from pymongo import MongoClient
client = MongoClient()
# client2 = MongoClient('localhost', 27017)
# client3 = MongoClient('mongodb://localhost:27017')
# 显示数据库
dbs = client.list_database_names()
print(dbs)
# 进入某个数据库
db = client.blog
2 curd完整示例代码
from pymongo import MongoClient
from bson.objectid import ObjectId
class TestMongo(object):
def __init__(self):
self.client = MongoClient()
self.db = self.client['students']
def add_one(self):
'''新增数据'''
post ={
'name': 'ben',
'age': 18,
'sex': "male",
'grade': 80,
'adress': "china"
}
return self.db.students.insert_one(post)
#print(res,res.inserted_id) 查询插入id是否成功
def add_many(self):
'''新增多条数据'''
infos = [
{'name': 'ben', 'age': 18, 'sex': "male", 'grade': 80, 'adress': "china"},
{'name': 'sum', 'age': 19, 'sex': "male", 'grade': 75, 'adress': "china"},
{'name': 'lily', 'age': 16, 'sex': "female", 'grade': 90, 'adress': "china"},
{'name': 'teddy', 'age': 19, 'sex': "male", 'grade': 65, 'adress': "china"},
{'name': 'fluence', 'age': 18, 'sex': "female", 'grade': 80, 'adress': "china"}
]
## print(res,res.inserted_ids)查询id
return self.db.students.insert_many(infos)
def get_one(self):
'''查询一条数据时,返回的是一个字典'''
return self.db.students.find_one()
def get_more(self):
'''查询多条数据时返回的是可迭代对象可以用list()转换'''
return self.db.students.find({'age': 18})
def get_one_from_oid(self, oid):
'''查询指定ID的数据'''
obj = ObjectId(oid)
return self.db.students.find_one({'_id': obj})
def update_one(self):
'''修改一条数据'''
return self.db.students.update_one({'age': 20}, {'$set': {'x': 10}})
## print(res,dir(res),res.raw_result)修改数据结果
def update_many(self):
'''修改多条数据'''
return self.db.students.update_many({}, {'$set': {'age': 5}})
def dalete_one(self):
'''删除一条数据'''
return self.db.students.delete_one({'name': 'ben'})
## print(res,dir(res),res.raw_result)删除数据结果
def delete_many(self):
'''删除多条数据'''
return self.db.students.delete_many({'age': 24})
def main():
obj = TestMongo()
# rest = obj.add_one()
# print(rest)
# rest = obj.add_many()
# print(rest)
# rest = obj.get_one()
# print(rest)
# rest = obj.get_more()
# for i in rest:
# print(i['_id'])
# rest = obj.get_one_from_oid('5c68b5cb5a49891b40b8a18e')
# print(rest)
# rest = obj.update_one()
# print(rest)
# rest = obj.update_many()
# print(rest)
# rest = obj.delete_one()
# print(rest.delete_count)
# rest = obj.delete_many()
# print(rest.delete_count)
if __name__ == '__main__':
main()
3 sort,skip,limit用法
# skip sort limit
# res = list(MONGO.user_info.find({}).limit(5))
# print(len(res))
# res = list(MONGO.user_info.find({}).limit(5).skip(5))
# print(len(res),res)
# res = list(MONGO.user_info.find({}).sort("age",pymongo.DESCENDING))
# print(res)
4 bson ObjectID和字符串之间转换
import pymongo
from bson import ObjectId
import json
mongo_client = pymongo.MongoClient(host="127.0.0.1", port=27017)
MONGO = mongo_client["test1"]
# 查询数据
res = MONGO.user.find_one({"name": "tianjian"})
res['_id'] = str(res['_id']) #将objectID转换为str
print(res)
res = MONGO.user.find_one({"_id": ObjectId(res['_id'])}) #查询还必须使用ObjectID类型
print(res)
res['_id'] = str(res['_id']) #序列化需要转换为字符串str
res_json = json.dumps(res)
print(res_json)