二十七、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': '[email protected]',
'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': '[email protected]',
'qq': '87654321'
}
}
}
)
#更新內嵌文檔部分文檔字段
test.update_one(
{'name': 'aidon'},
{
'$set': {
'contact.emial': '[email protected]'
}
}
)
替換:
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