$facet(集計)
定義
$facet
同じ入力ドキュメントセット上の単一ステージ内の複数の 集計パイプラインを処理します。各サブパイプラインには出力ドキュメントに独自のフィールドがあり、その結果はドキュメントの配列として保存されます。
$facet
ステージでは、1 つの集計ステージ内で複数のディメンションまたはファセットにわたるデータを特徴付ける多面的な集計を作成できます。ファセット集計により、データの参照と分析をガイドする複数のフィルターと分類が提供されます。小売業者は通常、商品の価格、メーカー、サイズなどのフィルターを作成して検索結果を絞り込むためにファセットを使用します。入力ドキュメントは
$facet
ステージに一度だけ渡されます。$facet
使用すると、入力ドキュメントを複数回取得する必要なく、同じ入力ドキュメント セットに対してさまざまな集計を実行できます。
互換性
次の環境でホストされる配置には $facet
を使用できます。
MongoDB Atlas はクラウドでの MongoDB 配置のためのフルマネージド サービスです
MongoDB Enterprise: サブスクリプションベースの自己管理型 MongoDB バージョン
MongoDB Community: ソースが利用可能で、無料で使用できる自己管理型の MongoDB のバージョン
構文
$facet
ステージの形式は次のとおりです。
{ $facet: { <outputField1>: [ <stage1>, <stage2>, ... ], <outputField2>: [ <stage1>, <stage2>, ... ], ... } }
指定した各パイプラインの出力フィールド名を指定します。
Considerations
$facet
の各ステージが実行されると、結果のドキュメントは 100 メガバイトに制限されます。$facet
ディスクに書き出すことができないため、 allowDiskUseフラグは 100 メガバイトのサイズ制限に影響しないことに注意してください。
最終出力ドキュメントは、16 メガバイトのBSON ドキュメント サイズ制限の対象となります。16 メガバイトを超えると、集計でエラーが発生します。
動作
ファセット関連の集計ステージでは、受信したドキュメントを分類してグループ化します。さまざまな $facet
サブパイプラインの <stage>
内の以下のファセット関連ステージのいずれかを指定して、多面的な集計を実行します。
$facet
では他の集計ステージも使用できます。ただし、次の例外があります。
$facet
内の各サブパイプラインには、まったく同じ入力ドキュメントのセットが渡されます。これらのサブパイプラインは互いに完全に独立しており、それぞれのドキュメント配列出力は出力ドキュメントの別々のフィールドに保存されます。 1 つのサブパイプラインの出力を、同じ $facet
ステージ内の別のサブパイプラインの入力として使用することはできません。 さらに集計が必要な場合は、$facet
の後にステージを追加し、目的のサブパイプライン出力のフィールド名 <outputField>
を指定します。
インデックスの使用
パイプラインの順序によって、 $facet
ステージがインデックスを使用する方法が決まります。
$facet
ステージがパイプラインの最初のステージである場合、ステージはCOLLSCAN
を実行します。$facet
ステージは、パイプラインの最初のステージである場合、インデックスを使用しません。$facet
ステージがパイプラインの後半にあり、前のステージでインデックスが使用されている場合、$facet
の実行中はCOLLSCAN
はトリガーされません。
たとえば、$facet
ステージよりも前にある$match
または$sort
ステージはインデックスを使用することができ、$facet
ステージはCOLLSCAN
をトリガーしません。
最適化の提案については、「集計パイプラインの最適化」を参照してください。
例
在庫が次のartwork
コレクションに保存されているオンライン ストアを考えてみましょう。
{ "_id" : 1, "title" : "The Pillars of Society", "artist" : "Grosz", "year" : 1926, "price" : NumberDecimal("199.99"), "tags" : [ "painting", "satire", "Expressionism", "caricature" ] } { "_id" : 2, "title" : "Melancholy III", "artist" : "Munch", "year" : 1902, "price" : NumberDecimal("280.00"), "tags" : [ "woodcut", "Expressionism" ] } { "_id" : 3, "title" : "Dancer", "artist" : "Miro", "year" : 1925, "price" : NumberDecimal("76.04"), "tags" : [ "oil", "Surrealism", "painting" ] } { "_id" : 4, "title" : "The Great Wave off Kanagawa", "artist" : "Hokusai", "price" : NumberDecimal("167.30"), "tags" : [ "woodblock", "ukiyo-e" ] } { "_id" : 5, "title" : "The Persistence of Memory", "artist" : "Dali", "year" : 1931, "price" : NumberDecimal("483.00"), "tags" : [ "Surrealism", "painting", "oil" ] } { "_id" : 6, "title" : "Composition VII", "artist" : "Kandinsky", "year" : 1913, "price" : NumberDecimal("385.00"), "tags" : [ "oil", "painting", "abstract" ] } { "_id" : 7, "title" : "The Scream", "artist" : "Munch", "year" : 1893, "tags" : [ "Expressionism", "painting", "oil" ] } { "_id" : 8, "title" : "Blue Flower", "artist" : "O'Keefe", "year" : 1918, "price" : NumberDecimal("118.42"), "tags" : [ "abstract", "painting" ] }
次のオペレーションでは、MongoDB のファセット機能を使用して、タグ、価格、作成年などの複数のディメンションで分類されたストアの在庫を顧客に提供します。この$facet
ステージには、この多面的な集計を実行するために$sortByCount
、 $bucket
、または$bucketAuto
を使用する 3 つのサブパイプラインがあります。 artwork
からの入力ドキュメントは、操作の開始時にデータベースから 1 回だけ取得されます。
db.artwork.aggregate( [ { $facet: { "categorizedByTags": [ { $unwind: "$tags" }, { $sortByCount: "$tags" } ], "categorizedByPrice": [ // Filter out documents without a price e.g., _id: 7 { $match: { price: { $exists: 1 } } }, { $bucket: { groupBy: "$price", boundaries: [ 0, 150, 200, 300, 400 ], default: "Other", output: { "count": { $sum: 1 }, "titles": { $push: "$title" } } } } ], "categorizedByYears(Auto)": [ { $bucketAuto: { groupBy: "$year", buckets: 4 } } ] } } ])
この操作を実行すると次のドキュメントが返されます。
{ "categorizedByYears(Auto)" : [ // First bucket includes the document without a year, e.g., _id: 4 { "_id" : { "min" : null, "max" : 1902 }, "count" : 2 }, { "_id" : { "min" : 1902, "max" : 1918 }, "count" : 2 }, { "_id" : { "min" : 1918, "max" : 1926 }, "count" : 2 }, { "_id" : { "min" : 1926, "max" : 1931 }, "count" : 2 } ], "categorizedByPrice" : [ { "_id" : 0, "count" : 2, "titles" : [ "Dancer", "Blue Flower" ] }, { "_id" : 150, "count" : 2, "titles" : [ "The Pillars of Society", "The Great Wave off Kanagawa" ] }, { "_id" : 200, "count" : 1, "titles" : [ "Melancholy III" ] }, { "_id" : 300, "count" : 1, "titles" : [ "Composition VII" ] }, { // Includes document price outside of bucket boundaries, e.g., _id: 5 "_id" : "Other", "count" : 1, "titles" : [ "The Persistence of Memory" ] } ], "categorizedByTags" : [ { "_id" : "painting", "count" : 6 }, { "_id" : "oil", "count" : 4 }, { "_id" : "Expressionism", "count" : 3 }, { "_id" : "Surrealism", "count" : 2 }, { "_id" : "abstract", "count" : 2 }, { "_id" : "woodblock", "count" : 1 }, { "_id" : "woodcut", "count" : 1 }, { "_id" : "ukiyo-e", "count" : 1 }, { "_id" : "satire", "count" : 1 }, { "_id" : "caricature", "count" : 1 } ] }