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 文档大小限制之内。

  • $sort阶段之前的$facet阶段无法确定顺序敏感累加器($first、、、$last、或$mergeObjects)在$push$firstN$lastN、或$bucketAuto阶段中的顺序$bucket,而该顺序必须跨界应用。$group $facet无论分组阶段是在$facet子管道内还是在$facet阶段之后,这都适用。在这种情况下,Amazon DocumentDB 会返回错误,而不是运行管道。要订购这样的累加器,请将$sort舞台放在分组阶段之前的$facet子管道内。 Order-insensitive 蓄能器(如$sum$min、$max$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()