- Mongo引擎教程
- MongoEngine - 主页
- MongoEngine——MongoDB
- MongoEngine - MongoDB 指南针
- MongoEngine - 对象文档映射器
- MongoEngine - 安装
- MongoEngine - 连接到 MongoDB 数据库
- MongoEngine - 文档类
- MongoEngine - 动态模式
- MongoEngine - 字段
- MongoEngine - 添加/删除文档
- MongoEngine - 查询数据库
- MongoEngine - 过滤器
- MongoEngine - 查询运算符
- MongoEngine - 查询集方法
- MongoEngine - 排序
- MongoEngine - 自定义查询集
- MongoEngine - 索引
- MongoEngine - 聚合
- MongoEngine - 高级查询
- MongoEngine - 文档继承
- MongoEngine - 原子更新
- MongoEngine-Javascript
- MongoEngine-GridFS
- MongoEngine - 信号
- MongoEngine - 文本搜索
- MongoEngine - 扩展
- MongoEngine 有用资源
- MongoEngine - 快速指南
- MongoEngine - 有用的资源
- MongoEngine - 讨论
MongoEngine - 聚合
术语“聚合”用于处理数据并返回计算结果的操作。对集合中的一个或多个文档字段求和、计数和平均值可以称为聚合函数。
MongoEngine提供了aggregate()函数,封装了PyMongo的聚合框架。聚合操作使用集合作为输入并返回一个或多个文档作为结果。
MongoDB 使用数据处理管道的概念。一条管道可以有多个阶段。基本阶段提供了类似查询的过滤和操作。其他提供了按一个或多个字段进行分组和/或排序的工具、字符串连接任务、数组聚合工具等。
MongoDB 管道创建中定义了以下阶段 -
姓名 | 描述 |
---|---|
$项目 | 通过添加新字段或删除现有字段来重塑流中的每个文档。 |
$匹配 | 过滤文档流以仅允许匹配的文档未经修改地传递到下一阶段。$match 使用标准 MongoDB 查询。 |
$编辑 | 通过根据文档本身存储的信息限制每个文档的内容来重塑每个文档。 |
$限额 | 限制不加修改地传递到管道的文档 |
$跳过 | 跳过前 n 个文档,并将未修改的剩余文档传递到管道。 |
$组 | 按给定标识符表达式对输入文档进行分组,并将累加器表达式应用于每个组。输出文档仅包含标识符字段和累积字段。 |
$排序 | 按指定的排序键对文档流重新排序。 |
$出 | 将聚合管道的结果文档写入集合。 |
聚合表达式使用字段路径来访问输入文档中的字段。要指定字段路径,请使用在字段名称前面加上美元符号 $$$ 前缀的字符串。表达式可以使用一个或多个布尔运算符($and、$or、$not)和比较运算符($eq、$gt、$lt、$gte、$lte 和 $ne)。
以下算术表达式也用于聚合 -
$添加 | 添加数字以返回总和。接受任意数量的参数表达式 |
$减去 | 返回第一个值减去第二个值的结果 |
$乘 | 将数字相乘以返回乘积。接受任意数量的参数表达式 |
$除法 | 返回第一个数字除以第二个数字的结果。接受两个参数表达式 |
$mod | 返回第一个数字除以第二个数字的余数。接受两个参数表达式 |
以下字符串表达式也可以用于聚合 -
$连接 | 连接任意数量的字符串 |
$子字符串 | 返回字符串的子字符串,从指定索引位置开始直到指定长度 |
降低$ | 将字符串转换为小写。接受单个参数表达式 |
$到上层 | 将字符串转换为大写。接受单个参数表达式 |
$strcasecmp | 执行字符串比较,如果两个字符串相等则返回 0,如果第一个字符串大于第二个字符串则返回 1,如果第一个字符串小于第二个字符串则返回 -1 |
为了演示aggregate()函数在MongoEngine中的工作原理,我们首先定义一个名为orders的Document类。
from mongoengine import * con=connect('mydata') class orders(Document): custID = StringField() amount= IntField() status = StringField()
然后我们在订单集合中添加以下文档 -
_ID | 客户ID | 数量 | 地位 |
---|---|---|---|
对象 ID("5eba52d975fa1e26d4ec01d0") | A123 | 500 | A |
对象 ID("5eba536775fa1e26d4ec01d1") | A123 | 250 | A |
对象 ID(“5eba53b575fa1e26d4ec01d2”) | B212 | 200 | D |
对象 ID("5eba540e75fa1e26d4ec01d3") | B212 | 400 | A |
仅当状态等于“A”时,aggregate() 函数才用于查找每个 custID 的金额字段总和。因此,管道构造如下。
管道的第一阶段使用 $match 来过滤 status='A' 的文档。第二阶段使用 $group 标识符对 CustID 上的文档进行分组并执行金额求和。
pipeline = [ {"$match" : {"status" : "A"}}, {"$group": {"_id": "$custID", "total": {"$sum": "$amount"}}} ]
该管道现在用作aggregate() 函数的参数。
docs = orders.objects().aggregate(pipeline)
我们可以使用 for 循环迭代文档光标。完整的代码如下 -
from mongoengine import * con=connect('mydata') class orders(Document): custID = StringField() amount= IntField() status = StringField() pipeline = [ {"$match" : {"status" : "A"}}, {"$group": {"_id": "$custID", "total": {"$sum": "$amount"}}} ] docs = orders.objects().aggregate(pipeline) for doc in docs: print (x)
对于给定的数据,生成以下输出 -
{'_id': 'B212', 'total': 400} {'_id': 'A123', 'total': 750}