1. 连接mongo
需要知道mongoDB的地址、端口、授权用户、授权密码。一般情况下,技术都会给到数据分析人员这些信息。
python没有安装模块pymongo模块的,在cmd里面,pip install pymongo 进行安装。(具体操作可以自行百度)
##导入连接mongo需要的模块
from pymongo import MongoClient
###连接数据库
client = MongoClient(地址, 端口)
####访问数据库授权
db_auth = client.admin ##哪个库,这里是admin这个库
db_auth.authenticate(授权用户, 授权密码)
2. 访问数据集合并且提取数据
提取数据基本代码框架如下面代码示例:
collect10=db2.decisionResultData ##选择某个某个数据集合进行访问
###这里选择decisionResultData数据集合(相当于mysql里面的数据表)进行访问
dt= collect10.find({}) ###选择访问数据集合的所有数据
df_decision=pd.DataFrame(list(dt)) ####将这些数据转化为DataFrame格式
加入某些限制条件进行数据提取,在find字典里面进行条件设置。
dt= collect10.find({某些条件}) ###选择访问数据集合中符合某些条件的数据
df_decision=pd.DataFrame(list(dt)) ####将这些数据转化为DataFrame格式
3. 数据筛选条件
a. 大于/小于/等于条件
使用方式为:类似python中的字典嵌套字典的形式进行条件设置。
大于等于某个值
dt=collect10.find({'age':{'$gte':12
}
}
) ####年龄大于等于12岁
df_decision=pd.DataFrame(list(dt)) ####将这些数据转化为DataFrame格式
小于某个值,将上面代码中的 $gte 换为 $lt 即可
等于某个值,以字典形式传入值即可
dt=collect10.find({'age':12
}
) ####查询等于12岁的数据
df_decision=pd.DataFrame(list(dt)) ####将这些数据转化为DataFrame格式
关于时间范围的特殊示例。
Mongo数据集合中,有的是没有储存时间的,为了选取一定时间范围内的数据,可以利用集合表中的_id来进行时间范围的选择。
【_id是一个ObjectId类型的主键,其前4个字节是UNIX时间戳 。】
如果需要选择大于某个时间点后面的数据,根据需要的时间,生成一个ObjectId,条件设置为_id 大于这个ObjectId即可。
代码示例:
def object_id_from_datetime(from_datetime=None,span_days=0,span_hours=0,span_minutes=0,span_seconds=0,span_weeks=0):
'''根据时间手动生成一个objectid,此id不作为存储使用'''
if not from_datetime:
from_datetime = datetime.datetime.now()
from_datetime = from_datetime + datetime.timedelta(days=span_days,hours=span_hours,minutes=span_minutes,weeks=span_weeks)
return ObjectId.from_datetime(generation_time=from_datetime)
begin_date = input('请输入开始日期,格式例如:2017-01-31 00:00:00 :')
begin_date=object_id_from_datetime(datetime.datetime.strptime(begin_date,'%Y-%m-%d%H:%M:%S')-datetime.timedelta(hours=8))###减8个小时
dt= collect10.find({'_id':{'$gte':begin_date}}) ###大于等于开始时间的数据筛选条件
df_decision=pd.DataFrame(list(dt))###将数据转化为DataFrame格式
b. 包括/不包括条件
字典嵌套,'$in'的值为列表形式。
dt=collect10.find({'companyId':{'$in':['001','002']
}
}) ###提取companyId为001和002的数据
df_comp=pd.DataFrame(list(dt)) ####将这些数据转化为DataFrame格式
不在某些值中,将上面代码中的 $in 换为 $nin 即可。
c. 加入and /or 逻辑条件
并且的逻辑。字典里面的逗号就是表示and的逻辑。
dt=collect10.find({'age':{'$gte':12
,'$lte':18
}
}####年龄大于等于12岁并且小于等于18岁
)
df_decision=pd.DataFrame(list(dt)) ####将这些数据转化为DataFrame格式
或则和的逻辑。or字典,值为列表形式,列表里面以字典键值对形式进行或者条件的设置。
dt= collect10.find({'$or':[{'description':'BB'}
,{'name':'AA'}
]
})### description等于BB 并且 name等于AA的数据
df_3=pd.DataFrame(list(dt))
d. 限制输出条数
使用limit(number),number表示限制的条数。可以先看看数据输出的格式。
dt= collect10.find({'$or':[{'description':'BB'}
,{'name':'AA'}
]
}).limit(10) ### 只输出条数为10条
df_3=pd.DataFrame(list(dt))
e. 选择字段进行输出
可以不输出该数据集合中的所有字段,筛选某些字段输出。
格式为:collect2.find({ 筛选条件},{'字段A':1, '字段B':0,'字段C':1})。
在筛选条件之后,增加字段是否显示的字典键值对,0表示不显示(不输出),1表示显示(输出)。
dt=collect2.find({'$or':[{'description':'BB'}
,{'name':'AA'}
]
}
,{'name':1
,'_id':0
,'status':1
,'requestDuration':1
}
)
###选择description为BB或则name为AA的数据,并且只显示name、description、requestDuration这3个字段。
df_3=pd.DataFrame(list(dt))
f. 进行排序
使用的格式为:
按照某个字段升序排列:
访问的集合命名.find({}).sort('字段名称',pymongo.DESCENDING)
按照某个字段降序排列:
访问的集合命名.find({}).sort('字段名称',pymongo. ASCENDING)
多个字段综合排序:
访问的集合命名.find({}).sort([('字段A',pymongo.DESCENDING)
,('字段B',pymongo.ASCENDING)
,……
]
)
使用sort和limit 结合,可以输出某些排序靠前的数据。经常用来查看最近时间产生的一些数据。
以下代码选取最近10条数据。
#访问data这个数据库
db2=client['data']
###访问这个文档,数据调取记录
collect2=db2.loggerModel
dt= collect2.find({}).sort('_id',pymongo.DESCENDING).limit(10)
#pymongo.DESCENDING 表述倒叙 # pymongo.ASCENDING表示升序
df_3=pd.DataFrame(list(dt))
g. 统计一共多少条数据
代码格式有两种:访问的集合命名.find({ 筛选条件}).count()
访问的集合命名.count_documents({筛选条件})
这两个代码当前都可以不报错,但是第一个会提醒你,这个格式已经被取代了,建议使用第二个格式。大家还是习惯使用第二个吧。
#访问data这个数据库
db2=client['data']
###访问这个文档,数据调取记录
collect2=db2.loggerModel
collect2.count_documents({'$or':[{'description':'BB'}
,{'name':'AA'}
]
})
121963 ###输出结果,一共有121963条
h. 聚合计算,实现与sql代码一样的数据提取逻辑
使用aggregate(),使用格式为:
aggregate([操作标识1: {操作1}
,操作标识2: {操作2}
,操作标识3: {操作3}
,……
])
aggregate是一个管道的概念,操作1的输出结果作为操作2的输入数据,操作2的输出结果作为操作3的输入数据,以此类推。
aggregate 操作标识:
$project:修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档。
$match:用于过滤数据,只输出符合条件的文档。$match使用MongoDB的标准查询操作。
$limit:用来限制MongoDB聚合管道返回的文档数。
$skip:在聚合管道中跳过指定数量的文档,并返回余下的文档。
$unwind:将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值。
$group:将集合中的文档分组,可用于统计结果。
$sort:将输入文档排序后输出。
$geoNear:输出接近某一地理位置的有序文档。
在数据提取的时候,常用的操作标识有:$project、$match、$limit、 $group、$sort
$project
常用来筛选字段,以下代码表示只显示name、description、_id三个字段。(_id是默认显示的)
collect2.aggregate([{'$project':{'name':1
, 'description':1}
}
])
$match
数据过滤的操作,类似于sql的where条件,筛选条件的筛选方式如前面a、b、c所述。
collect2.aggregate([{'$match':{筛选条件}}
])
$limit
限制输出的条数
collect2.aggregate([{'$limit':10}
]) ##显示输出10条
$group
实现sql里面group by 的功能。
collect2.aggregate([{'$group': {'_id':"$字段名1" ##字段名称固定为'_id'
,'取个名字2':{'$聚合方式': '$字段名2'}
,'取个名字3':{'$聚合方式': '$字段名3'}
}
}
])
其中,字段名1为聚合的字段,也就是sql里面group by 后面的字段。字段名2是需要进行统计的字段。
示例如下:
dt=collect2.aggregate([{'$match':{'_id':{'$gte':begin_date}}} ##选择某个时间段之后的
,{'$group':{'_id':"$description"
,'num':{'$sum':1}
}
} ##统计有多少条数据,相当于count(1)
])
df_4=pd.DataFrame(list(dt))
多字段group by 的情况,'_id'的值变为字典键值对,字典里面键值对形式为'取个字段名称': '$字段名'。
示例为:
dt=collect2.aggregate([{'$match':{'_id':{'$gte':begin_date}}} ##选择某个时间段之后的
,{'$group':{'_id':{'description':"$description"
,'thirdPart':"$thirdPart"}
,'num':{'$sum': '$number'}
,'avgnum':{'$avg':'$number'}
,'minnum':{'$min':'$number'}
}
} ##group by description, thirdPart,对number字段进行求和、平均值、最小值操作
])
df_4=pd.DataFrame(list(dt))
聚合方式:
$max:返回最大值
$min:返回最小值
$avg:返回平均值
$sum:求和的操作
$first:第一个文档数据
$last:最后一个文档数据
$sort
排序,基本格式为:
collect2.aggregate([{'$ sort':{'字段名':1}}
])
按照字段名升序排列 ,1表示升序,-1表示降序
示例如下,按照条件筛选后,统计description分别的个数,再按照个数升序。
Sql代码逻辑:
select description
,count(*) num
from collect2
where _id>= begin_date
and _id<= end_date
and (description='BB' or name in ('AA','CC'))
group by description
order by count(*)
mongo代码实现:
dt=collect2.aggregate([{'$match':{'_id':{'$gte':begin_date
,'$lte':end_date}
,'$or':[{'description':'BB'}
,{'name':{'$in':['AA','CC']} }
]
}
}####先进行条件筛选
,{'$group':{'_id':"$description",'num':{'$sum':1}}}
,{'$sort':{'num':-1} }
])
df_4=pd.DataFrame(list(dt))