前兩天我們介紹了 aggregate 常用的 unwind、lookup、match 以及 group 這幾個操作符號,今天我們要來介紹 project 這個操作符號
$project
是 MongoDB 聚合管道中的一個階段,用於修改查詢結果的文件結構。它的主要用途如下:
字段選擇:您可以使用 $project
階段選擇要包含在查詢結果中的字段,以排除不需要的字段,從而減少數據傳輸和處理的開銷。這對於減小查詢結果文件的大小非常有用,特別是當您只關心特定字段時。
字段重命名:通過 $project
,您可以為字段指定新的名稱,以使查詢結果中的字段更容易理解或與其他數據集匹配。這對於數據清洗和整合非常有用。
計算新字段:您可以使用 $project
階段計算新的字段,這些字段可以基於現有字段的值進行計算。例如,您可以創建一個新的字段,它包含其他字段的和、差、平均值等聚合運算的結果。
陣列操作:如果您的文件包含陣列字段,$project
階段還可以用於篩選、重排或創建新的陣列字段。您可以選擇包含陣列中的特定元素,或者將陣列中的元素合併成一個新的陣列。
條件篩選:使用 $project
階段,您可以根據某些條件來選擇性地包含或排除文件。這使得您可以根據需要過濾數據,只返回符合特定條件的文件。
資料型別轉換:有時,文件中的字段可能存儲為不適合特定操作的資料型別。通過 $project
,您可以將字段的資料型別轉換為更適合您的操作的型別。
創建計算字段:您可以使用 $project
階段創建計算字段,這些字段的值可以基於文件中的其他字段進行計算。例如,您可以創建一個包含價格乘以數量的總價字段。
總之,$project
階段允許您在 MongoDB 聚合管道中對查詢結果進行自定義轉換和整理,以滿足您的具體需求。它是處理和準備數據的強大工具,使您能夠以適合您的方式呈現數據。
import os
from pathlib import Path
from dotenv import load_dotenv
from pymongo.database import Database
from pymongo.collection import Collection
from pymongo.mongo_client import MongoClient
from pprint import pprint
# 讀取 .env 取得連線資訊
BASE_DIR = Path(__file__).parent.parent
load_dotenv(str(BASE_DIR / ".env"))
# 取得所有 datas 檔案路徑下的所有檔案
file_names = []
for root, dirs, files in os.walk(BASE_DIR / "datas"):
for file in files:
file_path = os.path.join(root, file)
file_names.append(file_path)
# 建立 client 並與 db、collection 進行連線
client = MongoClient(host=os.getenv("MONGODB_ATLAS_URL"))
database = Database(client=client, name="HighRiskIntersection")
intersection_collection = Collection(database=database, name="Intersection")
# 使用 aggregate 和 project 查询数据
pipeline = [
{
"$lookup": {
"from": "Statistics",
"localField": "statistics_id",
"foreignField": "_id",
"as": "statistics"
}
},
{
"$unwind": "$statistics"
},
{
"$project": {
"_id": 0,
"year": 1,
"month": 1,
"rank": 1,
"jurisdiction": 1,
"intersection": 1,
"accident_time_interval": 1,
"cause": 1,
"city": 1,
"created_time": 1,
"A1_amount": "$statistics.A1_amount",
"A2_amount": "$statistics.A2_amount",
"A2_injury": "$statistics.A2_injury",
"A3_amount": "$statistics.A3_amount",
"total_amount": "$statistics.total_amount"
}
},
{
"$limit": 1
}
]
data = intersection_collection.aggregate(pipeline)
pprint(list(data))
client.close()
下方為範例輸出
[{'A1_amount': 0,
'A2_amount': 13,
'A2_injury': 16,
'A3_amount': 12,
'accident_time_interval': '14-16',
'cause': '未注意車前狀態',
'city': '台中市',
'created_time': datetime.datetime(2023, 9, 13, 20, 51, 49, 869000),
'intersection': '(西屯區)文心路與臺灣大道口',
'jurisdiction': '第六分局',
'month': 8,
'rank': 1,
'total_amount': 25,
'year': 2022}]
這個示例的用途是從 MongoDB 中檢索和整理與交通事故相關的數據,包括高風險交叉口的信息和有關該交叉口的統計數據。讓我更詳細地解釋一下:
MongoDB 數據庫:示例假設您正在使用 MongoDB 數據庫來存儲交通事故數據。在數據庫中,有兩個集合(或表),一個是包含高風險交叉口信息的集合(HighRiskIntersection),另一個是包含交通事故統計數據的集合(Statistics)。
Pydantic 模型:為了將數據插入數據庫和查詢數據,我們使用 Pydantic 創建了兩個模型(HighRiskIntersection 和 Statistics)。這些模型定義了數據的結構和字段。HighRiskIntersection 模型表示高風險交叉口的信息,而 Statistics 模型表示交通事故的統計數據。
MongoDB 查詢:示例中使用 MongoDB 的聚合操作(aggregate)來執行數據查詢。聚合操作允許我們以多個步驟來處理和篩選數據,以獲得所需的結果。在這個示例中,我們通過以下步驟來查詢數據:
$lookup 操作:首先,我們使用 $lookup 操作從 HighRiskIntersection 集合中關聯 Statistics 集合。這個操作通過模型中的 statistics_id 字段和 Statistics 集合中的 _id 字段將兩個集合連接起來。
$unwind 操作:接下來,我們使用 $unwind 操作展開關聯後的數組,以便後續操作可以處理單獨的文檔。
$project 操作:最後,我們使用 $project 操作來選擇和重命名字段,以創建一個新的文檔,其中包含了高風險交叉口信息和相關的交通事故統計數據。我們選擇了一些字段,如年份、月份、排名、轄區、路口等,以及與統計數據相關的字段,如 A1_amount、A2_amount 等。
查詢結果:執行聚合操作後,查詢結果將包含一個文檔列表,每個文檔都包含了高風險交叉口信息和相關的交通事故統計數據。這個結果可以用於生成報告、數據分析或其他用途。
總之,這個示例演示了如何使用 Pydantic 模型和 MongoDB 的聚合操作來查詢和整理與交通事故相關的數據。這種方法可以幫助您更有效地管理和分析大量的數據,以便做出有關交通安全的決策和報告。