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开发环境搭建
Dec 16 Python
Python父目录、子目录的相互调用方法
Feb 16 Python
Python实现的矩阵转置与矩阵相乘运算示例
Mar 26 Python
Ubuntu下Anaconda和Pycharm配置方法详解
Jun 14 Python
python如何保证输入键入数字的方法
Aug 23 Python
使用python将excel数据导入数据库过程详解
Aug 27 Python
Python3分析处理声音数据的例子
Aug 27 Python
Python django框架输入汉字,数字,字符生成二维码实现详解
Sep 24 Python
python文件和文件夹复制函数
Feb 07 Python
理解Django 中Call Stack机制的小Demo
Sep 01 Python
Pycharm快捷键配置详细整理
Oct 13 Python
Python使用windows设置定时执行脚本
Nov 12 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 增加了对 .ZIP 文件的读取功能
2006/10/09 PHP
php中看实例学正则表达式
2006/12/25 PHP
PHP 登录记住密码实现思路
2013/05/07 PHP
PHP.ini中配置屏蔽错误信息显示和保存错误日志的例子
2014/05/12 PHP
THINKPHP支持YAML配置文件的设置方法
2015/03/17 PHP
PHP闭包函数详解
2016/02/13 PHP
Codeigniter中集成smarty和adodb的方法
2016/03/04 PHP
PHP文件管理之实现网盘及压缩包的功能操作
2017/09/20 PHP
javascript Array.sort() 跨浏览器下需要考虑的问题
2009/12/07 Javascript
ExtJs默认的字体大小改变的几种方法(自己整理)
2013/04/18 Javascript
JavaScript程序开发之JS代码放置的位置
2016/01/15 Javascript
JS表单数据验证的正则表达式(常用)
2017/02/18 Javascript
微信小程序之购物车功能
2020/09/23 Javascript
使用pkg打包Node.js应用的方法步骤
2018/10/19 Javascript
vue项目部署到nginx/tomcat服务器的实现
2019/08/26 Javascript
解决Vue动态加载本地图片问题
2019/10/09 Javascript
Vuex,iView UI面包屑导航使用扩展详解
2019/11/04 Javascript
JavaScript禁止右击保存图片,禁止拖拽图片的实现代码
2020/04/28 Javascript
基于Web Audio API实现音频可视化效果
2020/06/12 Javascript
Pycharm学习教程(2) 代码风格
2017/05/02 Python
python获取文件路径、文件名、后缀名的实例
2018/04/23 Python
java中两个byte数组实现合并的示例
2018/05/09 Python
对Python中plt的画图函数详解
2018/11/07 Python
python PrettyTable模块的安装与简单应用
2019/01/11 Python
Python3 中sorted() 函数的用法
2020/03/24 Python
python 爬虫爬取京东ps4售卖情况
2020/12/18 Python
先进事迹报告会感言
2014/01/24 职场文书
《小熊住山洞》教学反思
2014/02/21 职场文书
商场促销活动总结
2014/07/10 职场文书
感恩节寄语2015
2015/03/24 职场文书
活动新闻稿范文
2015/07/17 职场文书
职工宿舍管理制度
2015/08/05 职场文书
应届生们该怎么书写求职信?
2019/07/05 职场文书
进阶篇之linux环境下安装MySQL数据库
2022/04/09 MySQL
5个实用的JavaScript新特性
2022/06/16 Javascript
Beekeeper Studio开源数据库管理工具比Navicat更炫酷
2022/06/21 数据库