pymongo中group by的操作方法教程


Posted in Python onMarch 22, 2019

前言

使用 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 默认返回浮点数。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对三水点靠木的支持。

Python 相关文章推荐
Python实现的百度站长自动URL提交小工具
Jun 27 Python
python Django模板的使用方法
Jan 14 Python
浅谈Python数据类型判断及列表脚本操作
Nov 04 Python
Python中 Lambda表达式全面解析
Nov 28 Python
python中 chr unichr ord函数的实例详解
Aug 06 Python
详解python中__name__的意义以及作用
Aug 07 Python
Python使用Opencv实现图像特征检测与匹配的方法
Oct 30 Python
Python单链表原理与实现方法详解
Feb 22 Python
python实现按键精灵找色点击功能教程,使用pywin32和Pillow库
Jun 04 Python
Ubuntu16安装Python3.9的实现步骤
Dec 15 Python
selenium如何定位span元素的实现
Jan 13 Python
python定义具名元组实例操作
Feb 28 Python
Python常用特殊方法实例总结
Mar 22 #Python
pymongo中聚合查询的使用方法
Mar 22 #Python
OpenCV HSV颜色识别及HSV基本颜色分量范围
Mar 22 #Python
基于OpenCV python3实现证件照换背景的方法
Mar 22 #Python
详解Python给照片换底色(蓝底换红底)
Mar 22 #Python
详解python-图像处理(映射变换)
Mar 22 #Python
python中如何使用分步式进程计算详解
Mar 22 #Python
You might like
php学习笔记 类的声明与对象实例化
2011/06/13 PHP
浅析php静态方法与非静态方法的用法区别
2016/05/17 PHP
JavaScript 异步调用框架 (Part 4 - 链式调用)
2009/08/04 Javascript
js如何实现设计模式中的模板方法
2013/07/23 Javascript
jQuery实现回车键(Enter)切换文本框焦点的代码实例
2014/05/05 Javascript
JavaScript数组排序reverse()和sort()方法详解
2017/12/24 Javascript
JavaScript实现简单动态进度条效果
2018/04/06 Javascript
详解vuex结合localstorage动态监听storage的变化
2018/05/03 Javascript
vue2.0+vuex+localStorage代办事项应用实现详解
2018/05/31 Javascript
Javascript实现一朵从含苞到绽放的玫瑰
2019/03/30 Javascript
JavaScript的Proxy可以做哪些有意思的事儿
2019/06/15 Javascript
微信小程序如何访问公众号文章
2019/07/08 Javascript
angularjs1.X 重构controller 的方法小结
2019/08/15 Javascript
JS阻止事件冒泡的方法详解
2019/08/26 Javascript
js实现简易计算器功能
2019/10/18 Javascript
[01:04:02]DOTA2-DPC中国联赛 正赛 Elephant vs IG BO3 第二场 1月24日
2021/03/11 DOTA
python字典序问题实例
2014/09/26 Python
利用Python实现颜色色值转换的小工具
2016/10/27 Python
python使用Matplotlib绘制分段函数
2018/09/25 Python
Python实现的多进程拷贝文件并显示百分比功能示例
2019/04/09 Python
在PyCharm中控制台输出日志分层级分颜色显示的方法
2019/07/11 Python
在vscode中配置python环境过程解析
2019/09/28 Python
使用TensorFlow搭建一个全连接神经网络教程
2020/02/06 Python
jupyter 使用Pillow包显示图像时inline显示方式
2020/04/24 Python
Python如何转换字符串大小写
2020/06/04 Python
Python批量获取并保存手机号归属地和运营商的示例
2020/10/09 Python
Pycharm编辑器功能之代码折叠效果的实现代码
2020/10/15 Python
德国50岁以上交友网站:Lebensfreunde
2020/03/18 全球购物
Pharmacy Online中文直邮网站:澳洲大型药房
2020/06/27 全球购物
个人实用的自我评价范文
2013/11/23 职场文书
祖国在我心中演讲稿
2014/01/15 职场文书
一夜的工作教学反思
2014/02/08 职场文书
《少年王冕》教学反思
2014/04/11 职场文书
人事文员岗位职责
2015/02/04 职场文书
入党后的感想
2015/08/10 职场文书
nginx处理http请求实现过程解析
2021/03/31 Servers