- 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}
廣告