实践环境

Python 3.6.4

pymongo 4.1.1

pymongo-3.12.3-cp36-cp36m-win_amd64.whl

下载地址:https://pypi.org/simple/pymongo/

代码实践

#!/usr/bin/env python
# -*- coding:utf-8 -*- import datetime
import random
import pymongo
from pymongo import MongoClient
from bson.objectid import ObjectId # # # # # # # # # 建立连接
# 方式1
# client = MongoClient() # 使用默认主机和端口连接本地Mongodb服务器 # 方式2:
# client = MongoClient("localhost", 27017) # 也可以手动指定服务器和端口 # 方式3:采用url
user_name = 'tcems'
password = 'Password123456' uri = f'mongodb://{user_name}:{password}@polartcems-mrs1.dbsit.sfcloud.local:24000,polartcems-mrs2.dbsit.sfcloud.local:24000,polartcems-mrs3.dbsit.sfcloud.local:24000'
client = MongoClient(uri) # # # # # # # # # 获取数据库信息
databases = client.list_databases()
for database in databases:
print(database) # 输出字典,形如:{'name': 'custom_db_name', 'sizeOnDisk': 5001216.0, 'empty': False} # # # # # # # # # 获取数据库
my_test_db = client.tcems
# my_test_db = client['tcems'] # 如果不支持.属性方式访问(比如test-db),可以考虑使用字典方式访问 # # # # # # # # # 获取当前数据库拥有的集合名称列表
collections = my_test_db.list_collection_names()
print(collections) # 输出名称列表,形如['YiLiuTemHumLog', 'test_collection', ...] # # # # # # # # # 获取集合
collection = my_test_db.test_collection
# collection = my_test_db['test_collection'] # 如果不支持.属性方式访问(比如test-db),可以考虑使用字典方式访问 # # # # # # # # # 索引
# 创建索引
# collection.create_index([("date", pymongo.ASCENDING)])
# collection.create_index([("field_name", pymongo.ASCENDING)], unique=True) # 创建唯一索引 # # # # # # # # # 集合文档操作
# # # # # # # # # 插入文档
# 逐条插入文档
post = {
'author': 'Mike',
'visitor_num': random.randint(0,100),
'text': 'blog post of Mike!',
'tags': ['mongodb', 'python', 'pymongo'],
'date': datetime.datetime.now(tz=datetime.timezone.utc)
} post_id = collection.insert_one(post).inserted_id # 注意:insert_one函数返回 pymongo.results.InsertOneResult对象
print(post_id, type(post_id)) # 输出形如:65a881fffa04b0dc0e7a74bc <class 'bson.objectid.ObjectId'> # 注意,获取的insert_id为 bson.objectid.ObjectId类型 try:
post['_id'] = post_id
collection.insert_one(post) # 运行报错: pymongo.errors.DuplicateKeyError: E11000 duplicate key error collection:...
except pymongo.errors.DuplicateKeyError:
print('id重复')
# do something # 批量插入文档
posts = [
{
'author': 'Mike',
'visitor_num': random.randint(0,100),
'text': 'blog post of Mike!',
'tags': ['mongodb', 'python', 'pymongo'],
'date': datetime.datetime.now(tz=datetime.timezone.utc)
},
{
'author': 'Jack',
'visitor_num': random.randint(0,100),
'text': 'blog post of Jack!',
'tags': ['mongodb', 'python', 'pymongo'],
'date': datetime.datetime.now(tz=datetime.timezone.utc)
}
]
res = collection.insert_many(posts) # insert_many函数返回 pymongo.results.InsertManyResult 对象
print(res.inserted_ids) # 获取插入记录的id,形如 [ObjectId('65a9423b782fc7838d729033'), ObjectId('65a9423b782fc7838d729034')]
inserted_ids = res.inserted_ids # # # # # # # # # 查询文档
# 查询单条文档
res = collection.find_one() # 注意:如果集合中存在记录,则find_one返回字典对象,否则返回None
print(res, type(res))
print(res.get('_id'), str(res.get('_id'))) # 获取插入时自动生成的文档ID # 查询时指定查询条件
print(collection.find_one({'author': 'Mike'})) # 文档author必须为Mike
print(collection.find_one({'_id': res.get('_id')})) # 按_id查询
print(collection.find_one({'_id': post_id})) # 注意:_id值类型必须为ObjectId # 批量查询
# 遍历所有记录
for post in collection.find():
print(post) # 此处,post为字典类型
break # 只查询满足条件的记录(注意:字典中逗号分隔的多个条件,默认的and关系
for post in collection.find({'visitor_num': {'$gte': 12, '$lte': 18}}): # 查找visitor_num大于等于12小于等于18的文档
print(post) for post in collection.find({'author': {'$ne': 'Mike'}}): # 查找 author 不等于 Mike的文档
print(post) for post in collection.find({'visitor_num': {'$ne': None}}): # 查找 visitor_num不为null的文档记录
print(post) for post in collection.find({'$or':[{'visitor_num':{'$gte':18}},{'author': 'Mike'}]}): # 查找 visitor_num 大于等于18,或者 author 等于 Mike 的文档
print(post) for post in collection.find({'visitor_num':{'$in': [58, 90, 41]}}): # 查找 visitor_num 值在数组 [58,90,41]中的文档
print(post) for post in collection.find({'author':{'$nin': ['Mike','Jack']}}): # 查找 visitor_num 不在数组 ['Mike','Jack'] 中的文档
print(post) # 限制返回文档数
for post in collection.find().limit(10): # 仅返回10条文档
print(post) # 查询排序
# 单个字段排序
# for post in collection.find().sort('visitor_num'): # 按 visitor_num 升序排序 # 注意:不存在排序字段的文档在有排序字段文档之上
for post in collection.find().sort('visitor_num', pymongo.ASCENDING): # 按 visitor_num 升序排序 pymongo.ASCENDING = 1
print(post) # 多字段排序
print('多字段排序1: 按 _id 升序,再按 visitor_num 降序')
for post in collection.find().sort([('_id', 1), ('visitor_num', pymongo.DESCENDING)]):
print(post) print('多字段排序2: 按 _id 降序,再按 visitor_num 升序')
for post in collection.find().sort([('_id', -1), ('visitor_num', 1)]):
print(post) # 聚合查询
start_time = datetime.datetime(2024, 1, 15, 6, 37, 37, 246000)
end_time = datetime.datetime(2024, 1, 15, 6, 44, 7, 239000) # 查询当前集合中最大,最小文档ID
for record in collection.aggregate([
{
"$group": {
"_id": None,
"min_id": {"$min": '$_id'},
"max_id": {"$max": '$_id'}
}
}
]):
if record: # record为字典类型
print(record.get('min_id'))
print(record.get('max_id')) # 查询当前集合中指定时间范围内最大,最小文档ID
for record in collection.aggregate([
{
'$match': {
'date': {'$gte': start_time, '$lte': end_time}},
},
{
"$group": {
"_id": None,
"min_id": {"$min": '$_id'},
"max_id": {"$max": '$_id'}
}
}
]):
if record: # record为字典类型
print(record.get('min_id'))
print(record.get('max_id')) # 聚合管道
# 查询文档,按visitor_num降序排序,限制返回文档数为10--获取visitor_num top 10的记录
for post in collection.find().sort('visitor_num', pymongo.DESCENDING).limit(10):
print(post)
# 或者
for post in collection.find().limit(10).sort('visitor_num', pymongo.ASCENDING):
print(post) # 分页查询
for post in collection.find().skip(5).limit(10): # skip(N) 跳过前N个文档,等价于mysql查询中的offset 根据limit参数值,返回第N+1条及往后文档
print(post) # 统计
# 获取文档总数
print(collection.count_documents({})) # 获取文档总数 # 注意:查询条件 {} 不能少,否则会报错
print(collection.count_documents({'author': 'Jack'})) # 获取author值为Jack的文档总数 # 获取最小值
min_visitor_num = collection.find_one(sort=[('visitor_num', pymongo.ASCENDING)]).get('visitor_num') # 获取最小 visitor_num
print('min_visitor_num', min_visitor_num) # 获取最大值
max_visitor_num = collection.find_one(sort=[('visitor_num', pymongo.DESCENDING)]).get('visitor_num') # 获取最大 visitor_num
print(collection.find_one(sort=[('visitor_num', pymongo.DESCENDING)])) # # # # # # # # # 更新文档
# 逐条更新
new_content = {
'author': 'Json',
'visitor_num': random.randint(0,100),
'text': 'blog post of Json!',
'tags': ['mongodb', 'python', 'pymongo'],
'date': datetime.datetime.now(tz=datetime.timezone.utc)
}
query_condition = {'_id': ObjectId('65a4d2b165b14a57a38a1504')}
collection.update_one(query_condition, {'$set': new_content})
print(collection.find_one({'_id': ObjectId('65a4d2b165b14a57a38a1504')})) # 查看更新后的文档 # 批量更新
query_condition = {'visitor_num': None}
collection.update_many(query_condition, {'$set': new_content}) # 批量更新visitor_num值为null的的文档内容为 new_content变量值 # # # # # # # # # 删除文档
# 逐条删除文档
res = collection.delete_one({'_id': post_id}) # 删除指定_id等于 post_id变量值的文档 # 注意:delete_one函数返回 pymongo.results.DeleteResult对象
# print(res.deleted_count, res.raw_result)
if res.deleted_count == 1:
print('删除成功') # 批量删除
res = collection.delete_many({'_id': {'$in': inserted_ids}}) # delete_many函数返回 pymongo.results.DeleteResult 对象
print(res.deleted_count) # 输出被删除文档数量 # 删除全部文档
collection.delete_many({}) # # # # # # # # # 删除集合
collection.drop()

说明:

  1. 如果连接用户名和密码包含诸如':', '/', '+''@'保留字符,则使用前应该先进行编码,如下:

    from urllib.parse import quote_plus
    
    user_name = quote_plus('@username')
    password = quote_plus('test_password+')
    host = 'project.example.local'
    port = 27017
    uri = f'mongodb://{user_name}:{password}@{host}:{port}'
    client = MongoClient(uri)
  2. 使用URI建立连接时,URI书写格式分这么几种情况:

    1. 需要验证密码

      uri = 'mongodb://user_name:password@host:port/authentication_database'

      说明:authentication_database :授权数据库,可选配,默认admin,如果不为admin时,必须显示指明,否则会报类似如下错误:

      pymongo.errors.OperationFailure: Authentication failed., full error: {'ok': 0.0, 'errmsg': 'Authentication failed.', 'code': 18, 'codeName': 'AuthenticationFailed'}
    2. 不需要密码验证

      uri = 'mongodb://host:port'
    3. 集群模式

      uri = 'mongodb://user_name:password@host1:port1,host2:port2,host3:port3,...hostN:portN/authentication_database'
  3. MongoDB中的集合和数据库,都是懒惰地创建的——在第一个文档插入其中时创建的。

    备注:笔者实践时发现,无法自动创建数据库和集合,会提示授权认证失败。

  4. MongoDB中的数据使用JSON样式的文档表示(和存储)。在PyMongo中,使用字典来表示文档。例如,以下字典可能用于表示博客文章:

    import datetime
    post = {
    "author": "Mike",
    "text": "My first blog post!",
    "tags": ["mongodb", "python", "pymongo"],
    "date": datetime.datetime.now(tz=datetime.timezone.utc),
    }

    注意,文档可以包含本地Python类型(如datetime.datetime实例),这些类型将自动转换为相应的BSON类型或从相应的BSON类型转换。

  5. 实践时遇到类似如下错误:

    pymongo.errors.ConfigurationError: Server at * reports wire version 5, but this version of PyMongo requires at least 6 (MongoDB 3.6).

    原因分析:

    错误信息提示来看,使用的PyMongo版本与MongoDB服务器的Wire版本不兼容。服务器wire版本为5,而该PyMongo要求至少wire版本6(MongoDB 3.6)

    解决方法:

    1. 升级MongoDB服务器:将MongoDB服务器升级到PyMongo所需的版本,即MongoDB 3.6或更高版本。

    2. 降级PyMongo版本:如果不能升级MongoDB服务器,可以尝试降级PyMongo版本,以匹配MongoDB服务器版本。

      笔者实践时选择了降低PyMongo版本为 pymongo-3.12.3-cp36-cp36m-win_amd64.whl

参考链接

https://pymongo.readthedocs.io/en/stable/tutorial.html

https://pymongo.readthedocs.io/en/stable/api/pymongo/cursor.html#pymongo.cursor.Cursor.sort

https://pymongo.readthedocs.io/en/stable/api/pymongo/collection.html#pymongo.collection.Collection.count_documents

https://www.mongodb.com/docs/manual/reference/operator/query/

https://www.mongodb.com/docs/manual/reference/operator/aggregation/

https://www.mongodb.com/docs/manual/reference/operator/aggregation-pipeline/

https://www.mongodb.com/docs/manual/reference/operator/aggregation/match/#mongodb-pipeline-pipe.-match

Python 基于pymongo操作Mongodb学习总结的更多相关文章

  1. python操作三大主流数据库(8)python操作mongodb数据库②python使用pymongo操作mongodb的增删改查

    python操作mongodb数据库②python使用pymongo操作mongodb的增删改查 文档http://api.mongodb.com/python/current/api/index.h ...

  2. Python 使用pymongo操作mongodb库

    Python 使用pymongo操作mongodb库 2016-12-31 21:55 1115人阅读 评论(0) 收藏 举报  分类: - - - Python(10)  版权声明:本文为博主原创文 ...

  3. python 通过pymongo操作mongoDB执行sort

    在mongo shell 中对数据进行排序操作的时候 db.getCollection('ANJUKE_PRICE').find({},{'id':1,'_id':0}).sort({'id':1}) ...

  4. PHP操作MongoDB学习笔记

    <?php/*** PHP操作MongoDB学习笔记*///*************************//**   连接MongoDB数据库  **////*************** ...

  5. MongoDB学习【四】—pymongo操作mongodb数据库

    一.pymongodb的安装 Python 要连接 MongoDB 需要 MongoDB 驱动,这里我们使用 PyMongo 驱动来连接. pip安装 pip 是一个通用的 Python 包管理工具, ...

  6. python使用pymongo访问MongoDB的基本操作,以及CSV文件导出

    1. 环境. Python:3.6.1 Python IDE:pycharm 系统:win7 2. 简单示例 import pymongo # mongodb服务的地址和端口号mongo_url = ...

  7. PHP操作MongoDB学习(转)

    1  mongodb启动时,设置启动项 C:\>mongodb\bin\mongod --config C:\mongodb.conf 其中mongodb.conf为:    dbpath = ...

  8. pymongo操作mongodb

    此验证中只开启两个mongodb节点,可以连接任意节点,以下操作不涉及读写,不涉及连接那个节点 mongodb连接: from pymongo import MongoReplicaSetClient ...

  9. Python操作MongoDB看这一篇就够了

    MongoDB是由C++语言编写的非关系型数据库,是一个基于分布式文件存储的开源数据库系统,其内容存储形式类似JSON对象,它的字段值可以包含其他文档.数组及文档数组,非常灵活.在这一节中,我们就来看 ...

  10. python操作mongodb

    # python操作mongodb # 首先,引入第三方模块pymongo,该模块是python用来操作mongodb的 import pymongo # 第二步,设置ip地址,以及表格名称,表格名字 ...

随机推荐

  1. redis 使用lua脚本 一次性获取多个hash key 字段值

    客户端命令行代码: eval "local rst={};local field='schoolid'; for i,v in pairs(KEYS) do rst[i]=redis.cal ...

  2. Android 13 - Media框架(6)- NuPlayer

    关注公众号免费阅读全文,进入音视频开发技术分享群! 上一节我们通过 NuPlayerDriver 了解了 NuPlayer 的使用方式,这一节我们一起来学习 NuPlayer 的部分实现细节. ps: ...

  3. python-一种去掉前后缀获取子串的方法

    假设有一个字符串,其数据组成方式为:"mode_id1_str_id2",其中id1和id2为任意个数的数字,若存在mode,则id1必然也存在,否则都不存在:id2可有可没有. ...

  4. 小程序的文件结构及配置 小程序配置 app.json

    程序包含一个描述整体程序的 app 和多个描述各自页面的 page. 一个小程序主体部分由三个文件组成,必须放在项目的根目录,如下: 文件 必填 作用 app.js 是 小程序逻辑-小程序入口文件 a ...

  5. React jsx中js表达式

    嵌入JS表达式 在jsx语法中,要把JS代码写到{ }中,所有标签必须要闭合. let num = 100 let bool = false; // JSX 语法 var myh1 = ( <d ...

  6. CSP-S2019 江西 题解

    为什么有 \(5\) 道题? [CSP-S2019 江西] 和积和 简单化一下式子: \[(n + 1) \times \sum A_i \times B_i - (\sum A_i) \times ...

  7. 再谈中断机制(APIC)

    中断是硬件和软件交互的一种机制,可以说整个操作系统,整个架构都是由中断来驱动的.一个中断的起末会经历设备,中断控制器,CPU 三个阶段:设备产生中断信号,中断控制器翻译信号,CPU 来实际处理信号. ...

  8. restTemplate.getForEntity restTemplate.getForObject GET请求

    //带参数 @Test public void testGet1(){ String url = "http://IP:PORT/query?token={token}&memNo= ...

  9. kooder安装及本地搜索git仓库代码

    kooder安装及本地搜索git仓库代码 需求背景:如果需要从Git代码仓库查询某个配置项做批量的更新替换,如果一个一个找不合适且容易遗漏,需要借助第三方工具来模糊查询来实现. 1.下载及文档地址ht ...

  10. c++引用(REFERENCES)

    一个例子 void add(int value) { value++; } int main() { int a = 5; LOG(a); add(a); LOG( a); } 在这种情况下,变量a在 ...