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常用内置模块之xml模块(详解)
May 23 Python
Zookeeper接口kazoo实例解析
Jan 22 Python
Python简单生成随机数的方法示例
Mar 31 Python
numpy中以文本的方式存储以及读取数据方法
Jun 04 Python
老生常谈python中的重载
Nov 11 Python
Python自动化完成tb喵币任务的操作方法
Oct 30 Python
pytorch中使用cuda扩展的实现示例
Feb 12 Python
django使用F方法更新一个对象多个对象字段的实现
Mar 28 Python
Python持续监听文件变化代码实例
Jul 22 Python
python 检测图片是否有马赛克
Dec 01 Python
python获取淘宝服务器时间的代码示例
Apr 22 Python
python数字类型和占位符详情
Mar 13 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
phpmyadmin操作流程
2006/10/09 PHP
Email+URL的判断和自动转换函数
2006/10/09 PHP
html中select语句读取mysql表中内容
2006/10/09 PHP
php adodb连接不同数据库
2009/03/19 PHP
php格式输出文件var_export函数实例
2014/11/15 PHP
PHP Web木马扫描器代码分享
2015/09/06 PHP
php排序算法实例分析
2016/10/17 PHP
PHP使用Redis替代文件存储Session的方法
2017/02/15 PHP
php+ajax实现无刷新文件上传功能(ajaxuploadfile)
2018/02/11 PHP
PHP观察者模式定义与用法实例分析
2019/03/22 PHP
学习jquery之一
2007/04/27 Javascript
javascript 哈希表(hashtable)的简单实现
2010/01/20 Javascript
js过滤数组重复元素的方法
2010/09/05 Javascript
用Jquery.load载入页面实现局部刷新
2014/01/22 Javascript
Javascript的严格模式strict mode详细介绍
2014/06/06 Javascript
TypeScript具有的几个不同特质
2015/04/07 Javascript
每天一篇javascript学习小结(Function对象)
2015/11/16 Javascript
JavaScript学习小结之使用canvas画“哆啦A梦”时钟
2016/07/24 Javascript
jQuery仿京东商城楼梯式导航定位菜单
2016/07/25 Javascript
input获取焦点时底部菜单被顶上来问题的解决办法
2017/01/24 Javascript
vue 项目中当访问路由不存在的时候默认访问404页面操作
2020/08/31 Javascript
Linux下使用python自动修改本机网关代码分享
2015/05/21 Python
Python的Django框架中自定义模版标签的示例
2015/07/20 Python
python爬虫面试宝典(常见问题)
2018/03/02 Python
python实现移位加密和解密
2019/03/22 Python
Python如何在单元测试中给对象打补丁
2020/08/03 Python
白俄罗斯大卖场:21vek.by
2019/07/25 全球购物
客服专员岗位职责范本
2013/11/29 职场文书
运动会邀请函范文
2014/01/31 职场文书
司机职责范本
2014/03/08 职场文书
《花瓣飘香》教学反思
2014/04/15 职场文书
房地产公司见习自我鉴定
2014/04/28 职场文书
岗位工作说明书
2014/07/29 职场文书
2016年党员创先争优公开承诺书
2016/03/25 职场文书
《家庭教育》读后感3篇
2019/12/18 职场文书
MySql数据库 查询时间序列间隔
2022/05/11 MySQL