$facet (多面集計)
最終更新:2026-10-09
$facet (多面集計)
$facet は、1 つのステージ内で複数のサブパイプラインを並行実行し、それぞれ同じ入力ドキュメントを処理して、結果をフィールドとしてまとめます: { name: [ 結果 ] }。サマリー統計、詳細リスト、上位 N 件を、複数回のラウンドトリップなしに 1 リクエストで取得できます。サブパイプラインは互いに独立です。
| カテゴリ | グループ化とウィンドウ |
|---|---|
| MongoDB バージョン | 1.0+ |
| 例の言語 | mongosh(シェル) |
📝 構文
{ $facet: { <outputField1>: [ <sub-pipeline1> ], <outputField2>: [ <sub-pipeline2> ] } }
⚙️ パラメータ
| サブパイプライン | フィールド名をサブパイプライン配列にマッピングします。各配列は入力を個別に処理します。 |
|---|
戻り値:各サブパイプラインの結果配列をフィールドに持つ単一のドキュメント
▶ 例
以下のコマンドをローカルの mongosh で実行してください(mongod が起動済みである必要があります):
// $facet: ステータス別の内訳と金額上位 5 件を同時に取得
db.orders.aggregate([
{ $facet: {
byStatus: [{ $group: { _id: '$status', n: { $sum: 1 } } }],
top5: [{ $sort: { amount: -1 } }, { $limit: 5 }]
} }
])
出力:
{ "byStatus": [ { "_id": "A", "n": 20 } ], "top5": [ { ... } ] }
📌 注意事項
- サブパイプラインには $out、$merge、$facet などのステージを入れられない
- サブパイプラインは独立で、それぞれが完全な入力を参照する
- 出力は 1 つのドキュメントで、サブパイプライン名ごとに配列が入る
🏷️ 関連タグ
💡 関連ケース
📚 関連チュートリアル
❓ よくある質問
Q$facet 内のサブパイプラインでソートできますか?
Aはい。サブパイプラインには $sort や $limit などの通常ステージを使えます。
Q$facet は複数回の aggregate 呼び出しより速いですか?
A通常は速いです。1 回のパスで複数の集計をまかなえるため、IO とラウンドトリップが減ります。
Q$facet の出力形式は?
A1 つのドキュメントで、サブパイプライン名が結果の配列にマッピングされます。