- MongoEngine 教程
- MongoEngine - 首页
- MongoEngine - MongoDB
- MongoEngine - MongoDB Compass
- MongoEngine - 对象文档映射器
- MongoEngine - 安装
- MongoEngine - 连接到 MongoDB 数据库
- MongoEngine - 文档类
- MongoEngine - 动态模式
- MongoEngine - 字段
- MongoEngine - 添加/删除文档
- MongoEngine - 查询数据库
- MongoEngine - 过滤器
- MongoEngine - 查询运算符
- MongoEngine - QuerySet 方法
- MongoEngine - 排序
- MongoEngine - 自定义 Query Sets
- MongoEngine - 索引
- MongoEngine - 聚合
- MongoEngine - 高级查询
- MongoEngine - 文档继承
- MongoEngine - 原子更新
- MongoEngine - Javascript
- MongoEngine - GridFS
- MongoEngine - 信号
- MongoEngine - 文本搜索
- MongoEngine - 扩展
- MongoEngine 有用资源
- MongoEngine - 快速指南
- MongoEngine - 有用资源
- MongoEngine - 讨论
MongoEngine - 聚合
术语“聚合”用于处理数据并返回计算结果的操作。在集合中一个或多个文档字段上查找总和、计数和平均值可以称为聚合函数。
MongoEngine 提供了aggregate()函数,该函数封装了 PyMongo 的聚合框架。聚合操作使用集合作为输入,并返回一个或多个文档作为结果。
MongoDB 使用数据处理管道这一概念。一个管道可以有多个阶段。基本阶段提供过滤器和类似查询的操作。其他阶段提供用于根据一个或多个字段进行分组和/或排序、字符串连接任务、数组聚合工具等的工具。
以下是在 MongoDB 管道创建中定义的阶段:
名称 | 描述 |
---|---|
$project | 通过添加新字段或删除现有字段来重塑流中的每个文档。 |
$match | 过滤文档流,只允许匹配的文档以未修改的方式传递到下一阶段。$match 使用标准的 MongoDB 查询。 |
$redact | 通过根据文档本身存储的信息限制每个文档的内容来重塑每个文档。 |
$limit | 限制要以未修改的方式传递到管道的文档 |
$skip | 跳过前 n 个文档,并将剩余的文档以未修改的方式传递到管道。 |
$group | 根据给定的标识符表达式对输入文档进行分组,并将累加器表达式应用于每个组。输出文档仅包含标识符字段和累加字段。 |
$sort | 根据指定的排序键重新排序文档流。 |
$out | 将聚合管道的结果文档写入集合。 |
聚合表达式使用字段路径来访问输入文档中的字段。要指定字段路径,请使用以美元符号$作为前缀的字段名称的字符串。表达式可以使用一个或多个布尔运算符($and、$or、$not)和比较运算符($eq、$gt、$lt、$gte、$lte 和 $ne)。
以下算术表达式也用于聚合:
$add | 将数字相加以返回总和。接受任意数量的参数表达式 |
$subtract | 返回从第一个值减去第二个值的结果 |
$multiply | 将数字相乘以返回乘积。接受任意数量的参数表达式 |
$divide | 返回第一个数字除以第二个数字的结果。接受两个参数表达式 |
$mod | 返回第一个数字除以第二个数字的余数。接受两个参数表达式 |
以下字符串表达式也可以用于聚合:
$concat | 连接任意数量的字符串 |
$substr | 返回字符串的子字符串,从指定的索引位置开始到指定的长度 |
$toLower | 将字符串转换为小写。接受一个参数表达式 |
$toUpper | 将字符串转换为大写。接受一个参数表达式 |
$strcasecmp | 执行字符串比较,如果两个字符串等效则返回 0,如果第一个大于第二个则返回 1,如果第一个字符串小于第二个则返回 -1 |
为了演示aggregate()函数在 MongoEngine 中的工作原理,让我们首先定义一个名为 orders 的文档类。
from mongoengine import * con=connect('mydata') class orders(Document): custID = StringField() amount= IntField() status = StringField()
然后我们在 orders 集合中添加以下文档:
_id | custID | amount | status |
---|---|---|---|
ObjectId("5eba52d975fa1e26d4ec01d0") | A123 | 500 | A |
ObjectId("5eba536775fa1e26d4ec01d1") | A123 | 250 | A |
ObjectId("5eba53b575fa1e26d4ec01d2") | B212 | 200 | D |
ObjectId("5eba540e75fa1e26d4ec01d3") | B212 | 400 | A |
aggregate() 函数用于查找仅当 status 等于“A”时每个 custID 的 amount 字段的总和。因此,管道构建如下。
管道中的第一阶段使用 $match 过滤 status='A' 的文档。第二阶段使用 $group 标识符根据 CustID 对文档进行分组,并执行 amount 的总和。
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}
广告