python操作MONGODB数据库,提取部分数据再存储
目标:从一个数据库中提取几个集合中的部分数据,组合起来一共一万条。几个集合,不足一千条数据的集合就全部提取,够一千条的就用一万减去不足一千的,再除以大于一千的集合个数,得到的值即为所需提取文档的个数。从每个集合中提取的数据存放到新的对应集合中,新集合名称为原先集合加"_col"。
用到相关技术点:
操作MONGODB:
先通过IP和端口号连接到MONGODB所在的机器,得到一个MONGODB客户端对象,然后认证某个数据库的账号密码连接到该数据库,得到一个该数据库的对象。一个数据库下有很多集合(相当于SQL中的表),集合里数据存储格式是BSON(同JSON)格式,集合中有很多条文档(相当于SQL中的记录)。可以通过数据库对象得到一个集合的对象,通过集合的对象来进行数据库增删改查的操作。
MONGODB操作的函数:
创建数据库:mydb = myclient["runoobdb"]
查看该客户端的所有数据库:dblist = myclient.list_database_names()
判断数据库是否存在:if "runoobdb" in dblist: print("数据库已存在!")
创建集合:mycol = mydb["sites"]
查看该数据库的所有集合:collist = mydb. list_collection_names()
判断集合是否存在:if "sites" in collist: print("集合已存在!")
插入一个文档:
mydict = { "name": "RUNOOB", "alexa": "10000", "url": "https://www.runoob.com" }
x = mycol.insert_one(mydict)
print(x)
输出结果:<pymongo.results.InsertOneResult object at 0x10a34b288>
insert_one() 方法返回 InsertOneResult 对象,该对象包含 inserted_id 属性,它是插入文档的 id 值。print(x.inserted_id)。如果我们在插入文档时没有指定 _id,MongoDB 会为每个文档添加一个唯一的 id。
插入多个文档:
mylist = [ { "name": "Taobao", "alexa": "100", "url": "https://www.taobao.com" }, { "name": "QQ", "alexa": "101", "url": "https://www.qq.com" }, { "name": "Facebook", "alexa": "10", "url": "https://www.facebook.com" }, { "name": "知乎", "alexa": "103", "url": "https://www.zhihu.com" }, { "name": "Github", "alexa": "109", "url": "https://www.github.com" } ]
x = mycol.insert_many(mylist)
# 输出插入的所有文档对应的 _id 值
print(x.inserted_ids)
插入查询结果文档集:
x.insert_many(mycol.find())
查询一条数据:
x = mycol.find_one() print(x)
查询集合中所有数据:
for x in mycol.find():
print(x)
查询指定字段:
for x in mycol.find({},{ "_id": 0, "name": 1, "alexa": 1 }): ##0表示该字段不出现,1表示该字段出现。除了_id字段,其他字段数字要一致,即要么都为0要么都为1。
print(x)
条件查询:
等值查询:
myquery = { "name": "RUNOOB" }
mydoc = mycol.find(myquery)
for x in mydoc:
print(x)
非等值查询:
# (>) 大于 - $gt
# (<) 小于 - $lt
# (>=) 大于等于 - $gte
# (<= ) 小于等于 - $lte
#例:查询集合中age大于25的所有记录
for i in my_col.find({"age":{"$gt":25}}):
print(i)
正则表达式查询:
## 读取 name 字段中第一个字母为 "R" 的数据
yquery = { "name": { "$regex": "^R" } }
mydoc = mycol.find(myquery)
for x in mydoc:
print(x)
查询指定条数记录:
## 返回 3 条文档记录
myresult = mycol.find().limit(3)
# 输出结果
for x in myresult:
print(x)
查询结果集中第n条记录,及第n条记录某个字段的值:
## 查询按照alexa字段倒排后,第三条记录的alexa字段的值
condition = col.find().sort("alexa",-1)[3]["alexa"]
print(condition)
查询一个集合中总文档个数:
num_document = mycol.count_documents({})
print(num_document)
按照字段类型条件查找:
#找出name的类型是String的
for i in my_set.find({'name':{'$type':2}}):
print(i)
‘’‘类型对照列表'''
Double 1
String 2
Object 3
Array 4
Binary data 5
Undefined 6 已废弃
Object id 7
Boolean 8
Date 9
Null 10
Regular Expression 11
JavaScript 13
Symbol 14
JavaScript (with scope) 15
32-bit integer 16
Timestamp 17
64-bit integer 18
Min key 255 Query with -1.
Max key 127
limit和skip:
#limit()方法用来读取指定数量的数据
#skip()方法用来跳过指定数量的数据
#下面表示跳过两条数据后读取6条
for i in my_set.find().skip(2).limit(6):
print(i)
IN:
#找出age是20、30、35的数据
for i in my_set.find({"age":{"$in":(20,30,35)}}):
print(i)
OR:
#找出age是20或35的记录
for i in my_set.find({"$or":[{"age":20},{"age":35}]}):
print(i)
多级路径元素查找:
## 先插入一条数据
dic = {"name":"zhangsan",
"age":18,
"contact" : {
"email" : "1234567@qq.com",
"iphone" : "11223344"}
}
my_set.insert(dic)
#多级目录用. 连接
for i in my_set.find({"contact.iphone":"11223344"}):
print(i)
#输出:{'name': 'zhangsan', '_id': ObjectId('58c4f99c4fc9d42e0022c3b6'), 'age': 18, 'contact': {'email': '1234567@qq.com', 'iphone': '11223344'}}
排序:
## sort() 方法第一个参数为要排序的字段,第二个字段指定排序规则,1 为升序,-1 为降序,默认为升序。
## 对字段 alexa 按降序排序
mydoc = mycol.find().sort("alexa",-1)
for x in mydoc:
print(x)
删除一个文档:
## delete_one() 方法来删除一个文档,该方法第一个参数为查询对象,指定要删除哪些数据。
## 删除 name 字段值为 "Taobao" 的文档
myquery = { "name": "Taobao" }
mycol.delete_one(myquery)
# 删除后输出
for x in mycol.find():
print(x)
删除多个文档:
myquery = { "name": {"$regex": "^F"} }
x = mycol.delete_many(myquery)
print(x.deleted_count, "个文档已删除")
删除集合中所有文档:
## delete_many() 方法如果传入的是一个空的查询对象,则会删除集合中的所有文档
x = mycol.delete_many({})
print(x.deleted_count, "个文档已删除")
删除集合:
mycol = mydb["sites"]
mycol.drop() ## 如果删除成功 drop() 返回 true,如果删除失败(集合不存在)则返回 false
修改一条记录:
## update_one() 方法修改文档中的记录。该方法第一个参数为查询的条件,第二个参数为要修改的字段。如果查找到的匹配数据多余一条,则只会修改第一条。
myquery = { "alexa": "10000" }
newvalues = { "$set": { "alexa": "12345" } }
mycol.update_one(myquery, newvalues)
# 输出修改后的 "sites" 集合
for x in mycol.find():
print(x)
修改多条记录:
## 将查找所有以 F 开头的 name 字段,并将匹配到所有记录的 alexa 字段修改为 123
myquery = { "name": { "$regex": "^F" } }
newvalues = { "$set": { "alexa": "123" } }
x = mycol.update_many(myquery, newvalues)
print(x.modified_count, "文档已修改")
config.py
## 数据库URL
MONGO_URL = 'mongodb://123.456.789.123:27017/'
## 数据库名称
MONGO_DB = 'hellodb' mongodb_extract.py
#导入存储MONGODB数据库的配置信息
from config import *
import pymongo ## 定义一个mongodb客户端
client = pymongo.MongoClient(MONGO_URL)
## 连接数据库,账号密码认证
db = client[MONGO_DB]
db.authenticate("username", "password")
'''问题:此函数得到的平均数,可能有的集合文档数目达不到。或者说可以按照每个集合比例数目提取数据'''
def average_num():
'''返回一个不大于1000个文档的集合,所需提取文档的个数列表。使得所要提取的几个集合所有提取文档个数为10000。'''
## 所有不大于1000的集合中的文档个数之和
count = 0
## 不大于1000的集合个数
i = 0
## 大于1000的集合所需提取文档的个数的列表
extract_num = []
for collection in db.list_collection_names():
if "_col" not in collection:
col = db[collection]
num_document = col.count_documents({})
print(num_document)
if num_document <= 1000:
count += num_document
else:
i += 1
## (10000-所有<1000的集合的文档之和)/大于1000的集合个数,取整数
average = int((10000 - count) / i)
## (10000-所有<1000的集合的文档之和)% 大于1000的集合个数,求余
remainder = (10000 - count) % i
for j in range(i-1):
extract_num.append(average)
extract_num.append(average + remainder)
return extract_num
def extract_data():
'''取出所有数据'''
extract_num_list = average_num()
for collection in db.list_collection_names():
## 几个集合的名称,每个类一个集合
col = db[collection]
## 每个集合的文档个数
num_document = col.count_documents({})
if num_document <= 1000:
## 如果一个集合中文档数量不超过1000,全部提取存储
db[collection + "_col"].insert_many(col.find({},{"infoId":0,"update_author":0,"Customs":0,"Customs_branch":0}))
else:
## 如果集合文档大于1000,则提取根据日期排序最新的指定个数文档
## 指定数量文档为止的约束日期
condition = col.find().sort("report_time",-1)[extract_num_list.pop()]["report_time"]
## 将大于约束日期的数据提取并存储
db[collection + "_col"].insert_many(col.find({"report_time":{"$gte":condition}},{"infoId":0,"update_author":0,"Customs":0,"Customs_branch":0}))
def main():
extract_data()
if __name__ == '__main__':
main()
write_data.py
'''将提取后的数据集合分别写到对应的.json文件中'''
#导入存储MONGODB数据库的配置信息
from config import *
import pymongo
import json ## 定义一个mongodb客户端
client = pymongo.MongoClient(MONGO_URL)
## 连接数据库,账号密码认证
db = client[MONGO_DB]
db.authenticate("username", "password") for collection in db.list_collection_names():
if "_col" in collection:
col = db[collection]
with open(collection[:-4] + '.json', 'a', encoding='utf-8') as f: ## a表示文件可追加,编码utf-8防止中文乱码
for data in col.find():
#f.write(str(data) + '\n') ## str()写可以写入文件,但是写到文件中的每条数据不是json格式,而是字符串格式,json.dumps()写入的是json格式文件,也只有json格式文件才可用MONGODB客户端导入数据库。
f.write(json.dumps(data,ensure_ascii=False) + '\n') ## json.dumps()得到的数据默认是ascii编码,这里ensure_ascii=False不让它编码为ascii格式。
f.close()
参考:http://www.runoob.com/python3/python-mongodb.html
https://www.cnblogs.com/melonjiang/p/6536876.html
python操作MONGODB数据库,提取部分数据再存储的更多相关文章
- python操作三大主流数据库(10)python操作mongodb数据库④mongodb新闻项目实战
python操作mongodb数据库④mongodb新闻项目实战 参考文档:http://flask-mongoengine.readthedocs.io/en/latest/ 目录: [root@n ...
- python操作三大主流数据库(9)python操作mongodb数据库③mongodb odm模型mongoengine的使用
python操作mongodb数据库③mongodb odm模型mongoengine的使用 文档:http://mongoengine-odm.readthedocs.io/guide/ 安装pip ...
- python操作三大主流数据库(8)python操作mongodb数据库②python使用pymongo操作mongodb的增删改查
python操作mongodb数据库②python使用pymongo操作mongodb的增删改查 文档http://api.mongodb.com/python/current/api/index.h ...
- python操作三大主流数据库(7)python操作mongodb数据库①mongodb的安装和简单使用
python操作mongodb数据库①mongodb的安装和简单使用 参考文档:中文版:http://www.mongoing.com/docs/crud.html英文版:https://docs.m ...
- python操作mongodb根据_id查询数据的实现方法
python操作mongodb根据_id查询数据的实现方法 python操作mongodb根据_id查询数据的实现方法,实例分析了Python根据pymongo不同版本操作ObjectId的技巧, ...
- Python 操作 mongodb 数据库
原文地址:https://serholiu.com/python-mongodb 这几天在学习Python Web开发,于 是做准备做一个博客来练练手,当然,只是练手的,博客界有WordPress这样 ...
- python 操作mongoDB数据库
网上关于python 操作mongoDB的相关文章相对不是很多,并且质量也不是很高!下面给出一个完整的 增删改查示例程序! #!/usr/bin/python # -*- coding: utf-8 ...
- python操作mongodb数据库
一.MongoDB 数据库操作 连接数据库 import pymongo conn = pymongo.Connection() # 连接本机数据库 conn = pymongo.Connection ...
- 【转】Python操作MongoDB数据库
前言 MongoDB GUI 工具 PyMongo(同步) Motor(异步) 后记 前言 最近这几天准备介绍一下 Python 与三大数据库的使用,这是第一篇,首先来介绍 MongoDB 吧,,走起 ...
随机推荐
- 认识RabbitMQ交换机模型
前言 RabbitMQ是消息队列中间件(Message Queue Middleware)中一种,工作虽然有用到,但是却没有形成很好的整体包括,主要是一些基础概念的认识,这里通过阅读<Rabbi ...
- grafana使用详解--技术流ken
grafana简介 Grafana是一个跨平台的开源的度量分析和可视化工具,可以通过将采集的数据查询然后可视化的展示,并及时通知.它主要有以下六大特点: 1.展示方式:快速灵活的客户端图表,面板插件有 ...
- Django 系列博客(十四)
Django 系列博客(十四) 前言 本篇博客介绍在 html 中使用 ajax 与后台进行数据交互. 什么是 ajax ajax(Asynchronous Javascript And XML)翻译 ...
- 使用LR编写HTTP协议Json报文格式接口脚本实战
最近在做HTTP协议接口压测时,遇到一些编写脚本方面的问题,在这里总结记录下,以便以后温习,也希望能帮助到和我有同样困惑的朋友吧. //实战代码如下所示:Action() { lr_start_tra ...
- Runloop详解
RunLoop是iOS和OSX开发中非常基础的一个概念,这篇文章将从源码以及应用入手,介绍RunLoop的概念以及底层实现原理.本人看了一下RunLoop的英语源码,以及借鉴部分优秀博客,感谢!读完这 ...
- 第51章 内省端点(Introspection Endpoint) - Identity Server 4 中文文档(v1.0.0)
内省端点是RFC 7662的实现. 它可用于验证引用令牌(如果消费者不支持适当的JWT或加密库,则可以使用JWT).内省端点需要身份验证 - 因为内省端点的客户端是API,您可以在其上配置秘密ApiR ...
- 如何使用Dubbo 2.7.0和Spring boot实现FAT测试(Feature Acceptance Test)
在一个调用链非常长的功能中,如果想修改其中的一个特性,并进行测试,而又不影响该环境的其他用户使用现有功能.特性,例如: 1. A.B.C.D之间通过Dubbo实现远程调用 2. 这些模块可能有一个或者 ...
- set用法小结
set本质上是一棵红黑树,用法也就那么几个,插入删除lowerbound,再就是迭代器之类的 基本用法 begin()--返回指向第一个元素的迭代器 #include<cstdio> #i ...
- SAP MM 事务代码MI31之思考
SAP MM 事务代码MI31之思考 1 - MI01之痛 多年SAP项目实施实践中,笔者之前对于SAP系统里盘点凭证创建(MI01)事务代码里的输入界面很是不爽: 第一,MI01输入了一行数据以后, ...
- 基础环境系列:PHP7.3.0并连接pache/IIS和MySQL
版本: php7.3.0 MySQL8.0.12 Apache2.4 IIS8 一.下载PHP 1.下载php3.7 PHP版本:php7.3(7.3.0) 下载地址:https://windows ...