pymongo是否线程安全(pymongo中group by的操作方法教程)
pymongo是否线程安全
pymongo中group by的操作方法教程前言
使用 pymongo 进行 group by 操作有两种基本方式,他们都是 mongodb 的原生命令,于 Collection 对象上调用。
|
def aggregate( self , pipeline, * * kwargs): def group( self , key, condition, initial, reduce , finalize = None , * * kwargs): |
示例数据
演示用的数据为一个订单表,含有以下字段:
Order
_id: ObjectID
userid: int
itemid: int
amount: int
time: string
主要任务为:
- 统计某个时间区间内每个 userid 的订单数
- 统计某个时间区间内每组 (userid, itemid) 共售出多少 amount
即分别为:单键分组和多键分组
aggregate
聚合操作只接受一个列表类型的参数 —— pipeline。其每一个元素都是一步操作(stage)。全部可用的 stage 可参见:
https://docs.mongodb.com/manual/meta/aggregation-quick-reference/#stages
注意 pipline 里面的 stage 是有序且可重复的,mongodb 会顺序执行,因此一定要记得把像 $match 这样的 stage 放前面。
单键分组
|
start_time = '2010-10-10 00:00:00' end_time = '2010-10-10 23:59:59' match = { 'time' : { '$gte' : start_time, '$lte' : end_time, } } groupby = 'userid' group = { '_id' : "$%s" % (groupby if groupby else None ), 'count' : { '$sum' : 1 } } ret = collection.aggregate( [ { '$match' : match}, { '$group' : group}, ] ) >>> ret [{ '_id' : 123 , 'count' : 500 }, ...] |
$group 指定了返回数据的格式,其中 _id 字段是分组的键。
多键分组
|
groupby = [ 'itemid' , 'userid' ] group = { '_id' : {key: ( '$%s' % key) for key in groupby} or { 'None' : '$None' }, 'count' : { '$sum' : '$amount' } } ret = collection.aggregate( [ { '$match' : match}, { '$group' : group}, ] ) >>> ret [{ '_id' : { 'itemid' : 111 , 'user_id' : 123 }, 'count' : 100 }, ...] |
这里与单键分组的区别仅在于 _id 的类型,改成了一个字典,从而允许多键组合。
为了提高通用性,建议始终使用字典的格式。
另外,既然字符串和字典都可以做键,那么列表行不行呢?答案是不行,列表里的元素,(如 '$userid') 并不会被自动识别为字段,而是仅作一般字符串处理。
最后关于 aggregate 中可用的运算操作符,可参见:
https://docs.mongodb.com/manual/reference/operator/aggregation/#accumulators
如其中的 $addToSet 也是颇有用处,可以用来实现 “统计每个人都买过哪些 itemid” 这样的功能:
|
group = { '_id' : { 'userid' : '$userid' }, 'dist_itemids' : { '$addToSet' : '$itemid' }, } |
group
相较于 aggregate 的全能,group 是专门处理分组操作的一个命令,因此这个方法的参数也更明确,主要参数为:
- key list, 分组的键
- condition dict,过滤条件
- initial dict,初始值
- reduce string/bson.Code, js 的 reduce 函数
例:
|
key = [ 'userid' , 'itemid' ] condition = { 'time' : { '$gte' : start_time, '$lte' : end_time, } } initial = { 'count' : 0 } reducer = Code( """ function(obj, prev) { prev.count = prev.count + obj.amount } """ ) ret = collection.group(key, condition, initial, reducer) >>> ret [{ 'userid' : 110 , 'itemid' : 123 , 'count' : 500.0 }, ...] |
这里的分组数据聚合,是通过 reduce 函数实现的,这个函数与 python 的 reduce 不同,它不需要返回值,而是直接修改 prev 参数即可,这个参数会自动代入下一次调用。这可能是 js 的实现。
须注意的是 js 默认返回浮点数。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对开心学习网的支持。
原文链接:https://my.oschina.net/lionets/blog/727188
- SQL group by分组查询
- group by是底层如何实现分组的(group by 按某一时间段分组统计并查询推荐)
- MYSQL中GROUP BY不包含所有的非聚合字段时的注意事项
- mysql能groupby两个字段吗(MySQL group by语句如何优化)
- sql中having用法(sql中的 where 、group by 和 having 用法解析)
- mysql 查询语句group by用法(MySQL group by和order by如何一起使用)
- mysqlgroupby用法(MySQL Group by的优化详解)
- sql语句的groupby是做什么的(深入浅析SQL中的group by 和 having 用法)
- pymongo是否线程安全(pymongo中group by的操作方法教程)
- linq中group by
- sql语句groupby分组后怎么显示(SQL group by去重复且按照其他字段排序的操作)
- group by如何知道分了几组(详解partition by和group by对比)
- Google 推出了一个游戏生成器,让不会编程的你也能自己设计游戏(推出了一个游戏生成器)
- 二胎家庭老大爱闹情绪,用这招很有效(二胎家庭老大爱闹情绪)
- 一个30岁男人外遇失败的全过程(一个30岁男人外遇失败的全过程)
- 《无敌破坏王2》 不聊彩蛋,聊聊我从动画里看到的现实那些事儿(无敌破坏王2不聊彩蛋)
- 《寄生虫》 三观不正 人类悲欢从来不相通,感同身受也并非本能(寄生虫三观不正)
- 这部动漫中的女孩子,可比101女孩更加励志(这部动漫中的女孩子)
热门推荐
- 织梦文章发布页如何增加表单(织梦CMS列表页只显示一篇文章的解决办法)
- asp服务器记录怎么发布(asp服务器如何搭建)
- nginxmac启动脚本(Mac M1 Nginx 配置多站点的实现)
- 腾讯云服务器初始化操作(腾讯云服务器入门使用流程[新手必看教程])
- windows性能计数器与SQL Server Profiler 组合分析性能
- dedecms添加文档(Dedecms自定义模型解决会员无法投稿的方法)
- mysql怎么迁移数据(如何把本地mysql迁移到服务器数据库)
- sqlserver如何生成xml文件(实现SQL Server 原生数据从XML生成JSON数据的实例代码)
- sql怎么取随机数(SQLServer 使用rand获取随机数的操作)
- python爬百度api有次数限制吗(对python借助百度云API对评论进行观点抽取的方法详解)
排行榜
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9