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':'.*公司.*'} }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章