近日在处理数据的时候遇到一个问题,数据存储在MongoDB数据库(如图1),而MongoDB模式自由、具有很大的灵活性,可以把不同结构的文档存储在同一个数据库里,即表的字段不是完全固定的,当某个字段有值时就会显示该字段,而当该字段没有值时就不显示该字段。因此,同一个数据库表根据不同的条件查询得到的字段数可能会不一样,如图2可以看到按不同的SourceCode查询时,字段个数不同。现在想得到每个SourceCode下的数据包含哪些字段,而SourceCode取值有70多个,如果手动统计有点耗时,于是想到利用Python读取MongoDB数据来解决这一问题。
pymongo是Python中用来操作MongoDB的一个库。
pip install pymongo
连接MongoDB时,需要使用PyMongo库里面的MongoClient,可以直接传入MongoDB的连接字符串“mongodb://用户名:密码@IP:端口号/”,即以mongodb开头,依次传入用户名、密码、IP和端口号。如果端口号不给传递参数,默认为27017。
from pymongo import MongoClient
import pandas as pd
#方式一
client = MongoClient('mongodb://username:[email protected]:27017/')
MongoDB中可以建立多个数据库,因此需要指定要操作哪个数据库。
##指定要操作的数据库,test
db = client.test
每个数据库中有多个表,因此需要指定要操作哪个表。
##限定数据库表,InternationalData.ILO_Value_20201207
mycol = db["InternationalData.ILO_Value_20201207"]
前面提到,想查看每个SourceCode下的字段,因此需要先获取SourceCode的取值,直接运用distinct实现SourceCode的去重查询。
#获取SourceCode,直接从MongoDB查询获得
Scode = mycol.distinct( "SourceCode")
#print (Scode)
遍历SourceCode,利用find()实现按SourceCode查询。find()返回的是Cursor类型,它相当于一个生成器,需要遍历取到所有的结果,其中每个结果都是字典类型。
totalkey=[] #totalkey记录所有SourceCode的涉及到的字段列表
key=[]
record=[]
t=1 ## 记录第几个SourceCode
##遍历SourceCode
for code in Scode:
#code=code
print (t,code)
t+=1
##设置查询的条件
myquery={ "SourceCode" : code }
mydoc=mycol.find(myquery)
i=0 ## i记录每个SourceCode对应的记录数
keyvalue=[] #keyvalue记录每个SourceCode的字段列表
##遍历每个SourceCode下的记录
for x in mydoc:
#print (x)
i+=1
for j in x.keys(): ##遍历每条记录的字段
if j not in keyvalue:
keyvalue.append(j)
if j not in totalkey:
totalkey.append(j)
#print (keyvalue)
#print (i)
#data["SourceCode"].append(code)
key.append(keyvalue)
record.append(i)
data=pd.DataFrame()
print (data)
data["SourceCode"]=Scode
data["Keyvalue"]=key
data['record']=record
print(totalkey)
#print(data.head())
data.to_csv('data/result.csv',encoding='gb18030',index=1)
###获取分别按SourceCode查询后的字段集合
from pymongo import MongoClient
import pandas as pd
##连接MongoDB
client = MongoClient('mongodb://username:[email protected]:27017/')
##指定要操作的数据库,test
db = client.test
##获取数据库中的所有表
collection_list = db.list_collection_names()
print(collection_list)
##限定数据库表,InternationalData.ILO_Value_20201207
mycol = db["InternationalData.ILO_Value_20201207"]
#获取SourceCode
##方式一:SourceCode从excel中读取
'''
scode_data=pd.read_csv('data/SourceCode.csv',encoding='gb18030')
print(scode_data.head())
Scode=scode_data['SourceCode'].values
'''
##方式二:SourceCode直接从MongoDB查询获得
Scode = mycol.distinct( "SourceCode")
#print (Scode)
#方式三:直接写列表
#Scode=["ABW_A"]
totalkey=[] ##totalkey记录所有SourceCode的涉及到的字段列表
key=[]
record=[]
t=1 ## 记录第几个SourceCode
##遍历SourceCode
for code in Scode:
#code=code
print (t,code)
t+=1
##设置查询的条件
myquery={ "SourceCode" : code }
mydoc=mycol.find(myquery)
i=0 ## i记录每个SourceCode对应的记录数
keyvalue=[] #keyvalue记每个SourceCode的字段列表
##遍历每个SourceCode下的记录
for x in mydoc:
#print (x)
i+=1
for j in x.keys(): ##遍历每条记录的字段
if j not in keyvalue:
keyvalue.append(j)
if j not in totalkey:
totalkey.append(j)
#print (keyvalue)
#print (i)
#data["SourceCode"].append(code)
key.append(keyvalue)
record.append(i)
data=pd.DataFrame()
print (data)
data["SourceCode"]=Scode
data["Keyvalue"]=key
data['record']=record
print(totalkey)
#print(data.head())
data.to_csv('data/result.csv',encoding='gb18030',index=1)
ps:初衷是通过撰写博文记录自己所学所用,实现知识的梳理与积累;将其分享,希望能够帮到面临同样困惑的小伙伴儿。如发现博文中存在问题,欢迎随时交流~~