View a markdown version of this page

$facet - Amazon DocumentDB

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

$facet

8.0.2 版的新功能。

Amazon DocumentDB $facet 中的彙總階段會在同一組輸入文件的單一階段內處理多個彙總管道。每個輸出欄位都會定義自己的管道,而每個管道都會收到相同的輸入文件。這可讓您在單一查詢中計算數個獨立的彙總,例如計數、分組和摘要統計資料,而不是透過多個不同的查詢執行集合。

每個子管道都會獨立執行,並產生存放在其對應輸出欄位中的文件陣列。由於子管道不會共用狀態,因此一個管道的輸出不會影響另一個管道。

語法

{ $facet: { <outputField1>: [ <stage1>, <stage2>, ... ], <outputField2>: [ <stage1>, <stage2>, ... ], ... } }

參數

  • outputField (必要):輸出欄位的名稱,該欄位會保留其相關聯彙總管道的結果陣列。您可以指定一或多個輸出欄位。每個輸出欄位都會映射至套用至輸入文件的彙總管道階段陣列。

輸出

$facet 階段會傳回單一文件。您指定的每個輸出欄位都包含其對應子管道所產生的文件陣列。

限制

  • $facet 子管道不能包含下列階段:$changeStream、$collStats、 $facet(不允許巢狀)$geoNear、、$indexStats、$listSearchIndexes$merge、、$out$planCacheStats、$search、 $searchMeta和 $vectorSearch。

  • $facet 階段傳回的文件必須保持在 16 MB BSON 文件大小限制內。

  • $facet 階段前的$sort階段無法判斷 $first、 $push$firstN$lastN或 $bucketAuto階段中順序敏感累積器 ($last、$bucket、、 或 $mergeObjects) 的順序$group,前提是必須跨$facet邊界套用該順序。這適用於分組階段是否位於$facet子管道內或$facet階段之後。在此情況下,Amazon DocumentDB 會傳回錯誤,而不是執行管道。若要訂購此類累積器,請將$sort階段放在$facet子管道內,就在分組階段之前。不區分順序的累積器,例如 $sum、$max、 $min和 $count不受影響。

範例 (MongoDB Shell)

下列範例示範如何使用 $facet階段在單一查詢中的相同銷售資料上運算多個彙總。

建立範例文件

db.sales.insertMany([ { item: "abc", price: 10, quantity: 2, date: new Date("2020-09-01") }, { item: "def", price: 20, quantity: 1, date: new Date("2020-10-01") }, { item: "ghi", price: 5, quantity: 3, date: new Date("2020-11-01") }, { item: "jkl", price: 15, quantity: 2, date: new Date("2020-12-01") }, { item: "abc", price: 25, quantity: 1, date: new Date("2021-01-01") } ]);

查詢範例

下列命令$facet使用 在單一階段中計算每個項目銷售的總數量、整體價格統計資料和文件計數總計:

db.sales.aggregate([ { $facet: { "totalByItem": [ { $group: { _id: "$item", totalQuantity: { $sum: "$quantity" } } } ], "priceStats": [ { $group: { _id: null, avgPrice: { $avg: "$price" }, maxPrice: { $max: "$price" } } } ], "documentCount": [ { $count: "total" } ] } } ])

輸出

命令會傳回下列輸出:

[ { totalByItem: [ { _id: "abc", totalQuantity: 3 }, { _id: "def", totalQuantity: 1 }, { _id: "ghi", totalQuantity: 3 }, { _id: "jkl", totalQuantity: 2 } ], priceStats: [ { _id: null, avgPrice: 15, maxPrice: 25 } ], documentCount: [ { total: 5 } ] } ]

程式碼範例

若要檢視使用 $facet命令的程式碼範例,請選擇您要使用的語言標籤:

Node.js
const { MongoClient } = require('mongodb'); async function example() { const client = await MongoClient.connect('mongodb://<username>:<password>@<cluster-endpoint>:27017/?tls=true&tlsCAFile=global-bundle.pem&replicaSet=rs0&readPreference=secondaryPreferred&retryWrites=false'); const db = client.db('test'); const sales = db.collection('sales'); const result = await sales.aggregate([ { $facet: { "totalByItem": [ { $group: { _id: "$item", totalQuantity: { $sum: "$quantity" } } } ], "priceStats": [ { $group: { _id: null, avgPrice: { $avg: "$price" }, maxPrice: { $max: "$price" } } } ], "documentCount": [ { $count: "total" } ] } } ]).toArray(); console.log(result); client.close(); } example();
Python
from pymongo import MongoClient def example(): client = MongoClient('mongodb://<username>:<password>@<cluster-endpoint>:27017/?tls=true&tlsCAFile=global-bundle.pem&replicaSet=rs0&readPreference=secondaryPreferred&retryWrites=false') db = client['test'] sales = db['sales'] result = list(sales.aggregate([ { '$facet': { 'totalByItem': [ {'$group': {'_id': '$item', 'totalQuantity': {'$sum': '$quantity'}}} ], 'priceStats': [ {'$group': {'_id': None, 'avgPrice': {'$avg': '$price'}, 'maxPrice': {'$max': '$price'}}} ], 'documentCount': [ {'$count': 'total'} ] } } ])) print(result) client.close() example()