Python_MongoDB操作

1、Mongodb安裝

2、Mongodb使用文檔

3、Python_pymongo操作

(1)連接mongodb
  • 創建MongoDB連接對象client
import pymongo
client = pymongo.MongoClient(host='localhost',port=27017)
  • 指定數據庫,調用client的屬性school,即可返回school數據庫:
db = client["school"]
  • 指定集合,每個數據庫又包含許多集合(它們類似於關係型數據庫中的表),如集合students,如下命令便申明瞭Collection對象:
collection = db["students"]
  • 連接數據庫總的實現
import pymongo


def connect_mongodb(config, db_name, table_name, remote_db=False):
    """
    連接mongodb數據庫
    :param config: host,port,username,password等配置的字典
    :param db_name: 數據庫名稱
    :param table_name: 表名
    :param remote_db: False連接本地數據庫,True連接的是遠程數據庫
    :return: 
    """
    client = pymongo.MongoClient(host=config['host'], port=config['port'])
    db = client[db_name]
    if remote_db:
        db.authenticate(db['username'], db['password'])
    return db[table_name]


local_config = {
    "host": "localhost",
    "port": 27017,
}
table = connect_mongodb(local_config, "School", "students")
(2)插入數據
  • insert_one()插入單條數據(字典類型),
  • insert_many()插入多條數據(字典的列表)
  • 在MongoDB中每條數據其實都有一個_id屬性來唯一標識,如果沒有顯示指明該屬性,MongoDB會自動產生一個ObjectId類型的_id屬性
record1 = {'name': 'ShirMay1', 'age': 24, 'gender': 'felmale'}
record2 = {'name': 'Long', 'age': 26, 'gender': 'male'}
insert_result = table.insert_one(record1)  #insert_one()插入單條數據
table.insert_many([record1, record2])  #insert_many()插入多條數據
print(insert_result)
print(insert_result.inserted_id)
# 運行結果:
# <pymongo.results.InsertOneResult object at 0x0000000002860508>
# 5c9b36b5fe0bea232819c8e7
(3)查詢數據
  • find_one()查詢單條數據(返回字典類型)
  • find()查詢多條數據(返回生成器對象,迭代輸出爲字典類型)
  • 操作符合官方文檔

比較符號表:

符號 含義 示例
$lt 小於 {‘age’:{’$lt’:20}}
$gt 大於 {‘age’:{’$gt’:20}}
$lte 小於等於 {‘age’:{’$lte’:20}}
$gte 小於等於 {‘age’:{’$gte’:20}}
$ne 不等於 {‘age’:{’$ne’:20}}
$in 在範圍內 {‘age’:{’$in’:[20,23]}}
$nin 不再範圍內 {‘age’:{’$nin’:[20,23]}}

功能符號表:

符號 含義 示例 示例含義
$regex 匹配正則表達式 {‘name’:{’$regex’:’^M.*’}} name以M開頭
$exists 屬性是否存在 {‘name’:{’$exists’:True}} name屬性存在
$type 類型判斷 {‘age’:{’$type’:‘int’}} age的類型爲int
$mod 數字模操作 {‘age’:{’$mod’[5,0]} 年齡模5餘0
$text 文本查詢 {‘text:text':'search’:‘Mike’} text類型的屬性中包含Mike字符串
$where 高級條件查詢 {‘$where’:‘obj.fans_count==obj.follows_count’} 自身粉絲數等於關注數
from bson.objectid import ObjectId
# find_one()方法查詢name爲ShirMay1的數據
query_result = table.find_one({'name': 'ShirMay1'})
# 返回字典類型
print(query_result, type(query_result))
# find_one()方法根據ObjectId來查詢
query_result_id = table.find_one({'_id': ObjectId('5e88484902bf934ff513ef37')})
# find()方法查詢年齡大於20的數據
query_ages20 = table.find({'age': {'$gt': 10}})
print(query_ages20)
for result in query_ages20:
    print(result, type(result))
(4)查詢總量
  • count_documents()方法查詢記錄數,傳入字典類型
# 查詢總數
count = table.count_documents({})
print(count)
# 查詢指定條件的數量
count1 = table.count_documents({'age': 24})
print(count1)
(5)排序
  • sort()方法排序,pymongo.ASCENDING升序(先大寫字母后小寫字母排序),pymongo.DESCENDING降序;
sort_result = table.find().sort('name', pymongo.ASCENDING)
print([result['name'] for result in sort_result])
# 運行結果如下
# ['Hardon', 'Jordan', 'Kevin', 'Mike', 'ShirMay1']
(6)更新
  • update_one()方法,指定更新的條件和更新後的數據即可
  • 如:更新name爲Kevin的數據的年齡:首先指定查詢條件,然後將數據查詢出來,修改年齡後調用update_one()方法將原條件和修改後的數據傳入;
  • 然後調用matched_count,modified_count屬性,可以獲得匹配的數據條數和影響的數據條數
condition = {'name': 'Kevin'}
# update_one()更新name爲Kevin的數據的年齡
student = table.find_one(condition)
student['age'] = 24
result = table.update_one(condition, {'$set': student})
print(result)  # <pymongo.results.UpdateResult object at 0x0000000002A70B08>
print(result.matched_count, result.modified_count) # 1 1

# update_one()更新年齡大於20的年齡加1
condition = {'age': {'$gt': 20}}
result = table.update_one(condition, {'$inc': {'age': 1}})
print(result)  # <pymongo.results.UpdateResult object at 0x0000000002A707C8>
print(result.matched_count, result.modified_count)  # 1 1
  • update_many()方法,指定更新的條件和更新後的數據即可
# update_many()更新年齡大於20的年齡加1
condition = {'age': {'$gt': 20}}
result = table.update_many(condition, {'$inc': {'age': 1}})
print(result)  # <pymongo.results.UpdateResult object at 0x00000000029230C8>
print(result.matched_count, result.modified_count)  # 3 3
(7)偏移
  • 調用skip()方法,比如偏移2,就忽略前兩個元素,得到第三個及以後的元素;另外limit()方法可以指定取幾個結果
# 偏移
skip_result = table.find().sort('name', pymongo.ASCENDING).skip(2)
print([result['name'] for result in skip_result])  # ['Kevin', 'Mike', 'ShirMay1']
# 偏移取1個結果
skip_result1 = table.find().sort('name', pymongo.ASCENDING).skip(2).limit(1)
print([result['name'] for result in skip_result1])  # ['Kevin']
(8)刪除
  • delete_one()刪除第一條符合條件的數據
  • delete_many()刪除所有符合條件的數據
# 刪除
result = table.delete_one({'name': 'Kevin'})
print(result)   # <pymongo.results.DeleteResult object at 0x0000000002A774C8>
print(result.deleted_count)
result = table.delete_many({'age': {'$lt': 25}})  # 1
print(result.deleted_count)  # 3
(9)其他操作方法
  • find_one_and_delete()、find_one_and_replace()、find_one_and_update()

4、實例函數

(1)連接本地數據庫或者遠程數據庫
import pymongo


def connect_mongodb(config, db_name, table_name, remote_db=False):
    """
    連接mongodb數據庫
    :param config: host,port,username,password等配置的字典
    :param db_name: 數據庫名稱
    :param table_name: 表名
    :param remote_db: False連接本地數據庫,True連接的是遠程數據庫
    :return: 
    """
    client = pymongo.MongoClient(host=config['host'], port=config['port'])
    db = client[db_name]
    if remote_db:
        db.authenticate(db['username'], db['password'])
    return db[table_name]


local_config = {
    "host": "localhost",
    "port": 27017,
}
table = connect_mongodb(local_config, "School", "students")
(2)更新數據數據,有則更新,無則插入
import copy
import datetime
def update_db_record(collection, db_query, record):
    """
    更新數據數據,有則更新,無則插入
    :param collection: 表名
    :param db_query: 字典,查詢鍵,db_query = {"md5key": '1cffe16313113026764d99c582'}
    :param record: 插入的數據
    :return:
    如果update的更新參數upsert:true,不存在會插入一條新的記錄。
    $setOnInsert操作符會將指定的值賦值給指定的字段,
    如果存在那麼$setOnInsert操作符不做任何處理
    https://blog.csdn.net/yaomingyang/article/details/78791453
    """
    def build_db_record(record):
        set_data = copy.deepcopy(record)
        set_data["last_updated_time"] = datetime.datetime.utcnow()
        # 世界時間,比本地時間少8個小時
        set_on_insert = {"created_time": datetime.datetime.utcnow()} 
        db_record = {"$set": set_data, "$setOnInsert": set_on_insert}
        return db_record
    new_record = build_db_record(record)
    collection.update_one(db_query, new_record, True)
(3)修改字段鍵名
def rename_db_key(collection, before_name, after_name):
    """
    修改mongodb的鍵名
    :param collection: 表名
    :param before_name: 修改前的鍵名, 如:"company"
    :param after_name: 修改後的鍵名, 如:"company_name"
    :return: 
    """
    collection.update_many({}, {'$rename': {before_name: after_name}})
(4)輸出mongo的數據
def mongodb_out_record(collection):
    """
    mongodb的數據存儲到redis裏面
    :param collection: mongodb的表
    :return: 數據生成器
    """
    cursor = collection.find(no_cursor_timeout=True, batch_size=5)
    for record in cursor:
        yield record

(5)查詢數據庫記錄總數
# 查詢數據庫記錄總數
def query_db_records(collection):
    count = collection.count_documents({})
    print('數據庫記錄數:', count)
    return count
(6)查詢數據庫去重後的總數
def query_db_records_after_repeat(collection, record_key):
    """
    查詢數據庫去重後的總數
    :param collection: 表名
    :param record_key: 字符串,鍵名
    :return:
    """
    lis = []
    cursor = collection.find(no_cursor_timeout=True, batch_size=5)
    for record in cursor:
        lis.append(record[record_key])
    print('數據庫去重後總數:', len(set(lis)))
    return len(set(lis))
(7)刪除數據庫重複的數據
def delete_db_records_repeated(collection, record_key):
    """
    刪除重複數據
    :param collection: 表名
    :param record_key: 字符串,鍵名
    :return:
    """
    # record_key = 'md5key'
    lis, delete_count = [], 0
    cursor = collection.find(no_cursor_timeout=True, batch_size=5)
    for record in cursor:
        if record[record_key] in lis:
            result = collection.delete_one({record_key: record[record_key]})
            print('刪除數', result.deleted_count)
            delete_count += 1
        lis.append(record[record_key])
    print(f'數據庫已刪除總數:{delete_count}; 數據庫去重後總數: {len(set(lis))}')
(8)刪除數據庫指定的數據
# 刪除數據庫匹配的數據,並不是刪除重複數據
def delete_db_records_matching(collection, record_key, record_value_list):
    """
    刪除數據庫匹配的數據,並不是刪除重複數據
    :param collection: 表名
    :param record_key: 字符串,鍵名 :'md5key'
    :param record_value_list: 鍵名對應的value值列表:
        ['876f68ed4e3e5a2ad839f00b23a98', '3e4be58223c400cc3ae89ff13452']
    :return: 
    """
    result = collection.delete_many({record_key: {'$in': record_value_list}})
    print('數據庫已刪除總數:{}'.format(result.deleted_count))

5、mongodb其他操作

(1)設置用戶名和密碼
  • 終端輸入
mongo
db.system.users.find( )  查看有多少用戶
db.system.users.remove({user:"test"})  刪除用戶
use admin
db.createUser( { user: "admin", pwd: "123", roles: [ { role: "userAdminAnyDatabase", db: "admin" } ] } )
db.auth("admin","123")
(2)查詢數據長度大於的數據
{name:{$exists:true},$where:"(this.name.length > 3)"} 
(3)查詢某一時間範圍數據
{"last_updated_time" : { "$gte" : ISODate("2019-08-12T00:00:00Z"),"$lt" : ISODate("2019-08-30T00:00:00Z")}}
(4)正則匹配查詢包含某字符
{'developer': {'$regex':'.*公司.*'} }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章