二十七、python 操作mongodb
插入:
1、-Insert_one(doc)
2、-Insert_many(doc,ordered=True/False) True是一个文档一个文档插入,False就可以并行插入,一个文档插入失败并不影响别的文档的插入,如果是True则会影响。
Mongo没有事物功能,只有原子插入
安装pymongo:
pip install pymongo
安装好后,去引入测试下是否安装好
边写python的代码:
#from pymongo import mongo_client #也可以,该文件里面有MongoClient类
from pymongo import MongoClient
conn = MongoClient("192.168.216.7", 27017) #获取mongodb的连接
db = conn.qianfeng #获取mongodb中的数据库
test = db.test #获取该库下的集合
print db
test.remove(None) #先清空集合
#嵌套文档
aidon = {
'name': 'aidon',
'age': 30,
'sex': 'm',
'contact': {
'emial': 'aidon@qq.com',
'qq': '12345678'
}
}
bajie = {
'name': 'aidon',
'habit': {
'habit1': 'eat',
'habit2': 'sleep'
},
'age': 250
}
#1、插入单行
test.insert_one(aidon)
x = test.insert_one(bajie)
print type(x), x #所有这种打印信息都可以再交互式运行的方式去打印看看
print x.inserted_id
#2、批量插入
from faker import Factory
import random
def getFakerData(n=10):
userfaker = Factory.create()
lable = ['name', 'address', 'email', 'age']
result = []
for i in range(n):
x = [userfaker.name(), userfaker.address(), userfaker.email(), random.randint(10, 40)]
result.append(dict(zip(lable, x)))
return result
userinfo = getFakerData()
print userinfo
z = test.insert_many(userinfo,ordered=False)
print type(z),z
print z.inserted_ids #注意是ids哟
查询:
1、find(filter):返回游标 :
查询所有的操作符号,请参考官网。
代码:
#3、查询,基于插入来做的
import json
from bson import json_util #这儿的两个引入是用于输出json格式的数据
# cursor = test.find({}) #没有任何的查询条件
# cursor = test.find({'name': 'aidon'}) #按名字过滤
# cursor = test.find({'name': {'$in': ['aidon', 'bajie']}}) #In
# cursor = test.find({'age': {'$gt': 25}}) #大于25
# cursor = test.find({'age': {'$gt': 25}}).limit(2) #大于25 limit
# cursor = test.find({'name': {'$in': ['aidon', 'bajie']},'age': {'$gt': 25}}) #In and
# cursor = test.find({'$or': [{'name': {'$in': ['aidon', 'bajie']}},{'age': {'$gt': 25}}]}) #In or
cursor = test.find({'habit.habit2': 'sleep'}) #子文档和父文档一起查询
#打印结果集
for i in cursor:
print i
# print json.dumps(i, skipkeys=True, indent=1, default=json_util.default) #注意是dumps 和是json_util.default。
更新:
1、update_one(filter,update,upsert=True/False)
2、update_many(filter,update,upsert=True/False)
具体的跟多更新操作符,官网地址:https://docs.mongodb.com/manual/reference/operator/update/
更新代码:
#4、update
#$inc,如果记录中没有改字段,将会增加。用于数值型字段
test.update_many(
{}, #更新的条件,空的为所有
{
'$inc': {'age': 2} #先把bajie的age注释掉
}
)
#min 在当前值和更新的这个值选一个最小值来更新,如果没有该字段则增加一个且为当前值。 用于数值型。
test.update_many(
{
'name': {'$in': ['aidon', 'bajie']}
}, #更新的条件,空的为所有
{
'$min': {'age': 20} #先把bajie的age注释掉
}
)
#$currentDate
test.update_many(
{
'name': {'$in': ['aidon', 'bajie']}
}, #更新的条件,空的为所有
{
'$currentDate': {'create_time': True,#mongo默认使用isoDate,比我们正常时间早八个小时
'mod_time': {'$type': 'timestamp'}} #使用时间戳
}
)
#更新整个内嵌文档
test.update_one(
{'name': 'aidon'},
{
'$set': {
'contact': {
'emial': 'aidon@163.com',
'qq': '87654321'
}
}
}
)
#更新内嵌文档部分文档字段
test.update_one(
{'name': 'aidon'},
{
'$set': {
'contact.emial': 'aidon@gmail.com'
}
}
)
替换:
db.collection.findAndModify()
db.collection.replace_one()
代码:
#简单的替换,更多参数参考官网
test.replace_one(
{'name': 'bajie'},
{'age': 111} #它就没有$set操作符,只能整个文档替换
)
删除:
delete_one(filter)
delete_many(filter)
代码:
#删除,也可以用test.remove({'name': 'bajie'}) 它会提示用delete
test.delete_many(
{'name': 'bajie'}
)
查询同时更新:
Find_one_and_replace()
Find_one_and_delete()
Find_one_and_update()
findAndModify()
代码:
#find and update
result = test.find_one_and_update(
{}, #filter
{'$set': {'locked': 1},
'$inc': {'age': 2}
}, #更新哪些字段
projection={'age': True, 'name': True}, #返回的字段
sort=[('age', pymongo.DESCENDING)], #排序,因为只能更新一个
return_document=pymongo.ReturnDocument.BEFORE #返回的状态,before是修改之前的,after是修改之后
)
聚合操作:
聚合操作等价于关系数据库中的分组汇总统计,比如分组求和、最大值、最小值、平均值等
Mongo中可以通过几种方式实现聚合:聚合管道、mapreduce、单目的的聚合操作符
具体参考官网:https://docs.mongodb.com/manual/aggregation/
聚合管道:
https://docs.mongodb.com/manual/tutorial/aggregation-zip-code-data-set/
如同linux管道 (|, 有输入输出,和mr一样)
管道操作符
表达式操作符
Collection.aggregate([{stage1},{stage2},...])
将json格式的测试数据导入到mongodb中:
mongoimport -d qianfeng -c zipcodes --file /home/hadoop/zipscode.json --type json
mongo的数据导入、导出、备份、恢复:
Mongoimport、mongoexport、mongodump、mongorestore 加参数
更多参考官网:https://docs.mongodb.com/manual/reference/program/
代码:
from pymongo import MongoClient
import pymongo
conn = MongoClient("192.168.216.7", 27017) #获取mongodb的连接
db = conn.qianfeng #获取mongodb中的数据库
zip = db.zipcodes #获取该库下的集合
#排序,按照城市和州排序
cursor = zip.aggregate([
{'$sort': {'city': 1, 'state': 1}},
{
'$project': {
'_id': 0,
'state': 1,
'city': 1,
'pop': 1
}
}
])
#人口数量超过1000万的州。通过两个管道做,一、按州分组 二、过滤总人口大于1000万
cursor = zip.aggregate([
{'$group': {'_id': '$state', 'totalPop': {'$sum': '$pop'}}},
{'$match': {'totalPop': {'$gte': 10*1000*1000}}} #相当于having
])
#每个州的平均城市人口 。 总共分为3个stage来做
cursor = zip.aggregate([
{'$group': {'_id': {'state': '$state', 'city': '$city'}, 'pop': {'$sum': '$pop'}}},
{'$group': {'_id': '$_id.state', 'avgCityPop': {'$avg': '$pop'}}},
{'$sort': {'avgCityPop': 1}} #1:升序 -1:降序
])
#每个州人口最多和最少的城市
cursor = zip.aggregate([
{'$group': {'_id': {'state': '$state', 'city': '$city'}, 'pop': {'$sum': '$pop'}}},
{'$sort': {'pop': 1}}, #按分组后的总人口之和升序
{'$group': {'_id': '$_id.state',
'biggestCity': {'$last': '$_id.city'},
'biggestPop': {'$last': '$pop'},
'smallestCity': {'$first': '$_id.city'},
'smallestPop': {'$first': '$pop'},
}},
{
'$project': {
'_id': 0,
'biggestCity': {'city': '$biggestCity', 'pop': '$biggestPop'},
'smallestCity': {'city': '$smallestCity', 'pop': '$smallestPop'}
}
}
])
#打印结果集
for i in cursor:
print i