集計によるデータの変換
項目一覧
Overview
このガイドでは、 MongoDB PHPライブラリを使用して集計操作を実行する方法を学習できます。
集計操作により MongoDB コレクション内のデータが処理され、計算結果が返されます。 クエリ API の一部である MongoDB 集計フレームワークは、データ処理パイプラインの概念をモデル化したものです。 ドキュメントは 1 つ以上の ステージを含むパイプラインに投入され、そこで集計結果に変換されます。
集計操作は自動車工場に似ています。工場内の組立ラインには、ドリルや溶接機のような、特定の作業をするための専用工具を備えた組立ステーションがあります。未加工のパーツが工場に搬入され、組立ラインで完成品に加工、組み立てられます。
集計パイプラインは組み立てライン、集計ステージは組み立てステーション、演算子式は専用ツールです。
集計操作と検索操作の比較
検索操作を使用して、次のアクションを実行できます。
どのドキュメントを返すかを選ぶ
どのフィールドを返すかを選ぶ
結果を並べ替える
集計操作を使用して、次のアクションを実行できます。
検索操作の実行
フィールドの名前を変更する
フィールドを計算する
データを要約する
値をグループ化する
制限
集計操作を実行する際には、次の制限を考慮してください。
返されたドキュメントは、 BSONドキュメントサイズの制限である16メガバイトに違反することはできません。
パイプライン ステージには、デフォルトで100メガバイトのメモリ制限があります。 この制限を超えるには、
allowDiskUse
オプションをtrue
に設定するオプション配列を作成し、その配列をMongoDB\Collection::aggregate()
メソッドに渡します。
集計 API
PHPライブラリは、集計パイプラインを作成するための次の API を提供します。
配列API :集計ステージを指定する配列を渡して集計パイプラインを作成します。
集計ビルダー : ファクトリー メソッドを使用して集計パイプラインを作成し、アプリケーションの型安全性とデバッグ可能性を高めます。
以下のセクションでは、各APIの説明と、集計パイプラインの作成例を示します。
Array API
集計を実行するには、次のコードに示すように、パイプラインステージを含む配列をBSONドキュメントとして MongoDB\Collection::aggregate()
メソッドに渡します。
$pipeline = [ ['<stage>' => <parameters>], ['<stage>' => <parameters>], // ... ]; $cursor = $collection->aggregate($pipeline);
このセクションの例では、 Atlas サンプル データセットのsample_restaurants
データベースのrestaurants
コレクションを使用します。 MongoDB Atlas クラスターを無料で作成して、サンプル データセットをロードする方法については、 「 Atlas を使い始める 」ガイドを参照してください。
フィルターとグループの例
次のコード例では、ニューヨークの各地区のケーキの数のカウントを生成します。 そのために、次のステージを含む集計パイプラインを使用します。
$matchステージ
cuisine
フィールドに値'Bakery'
が含まれるドキュメントをフィルタリングします。$groupステージでは、一致するドキュメントを
borough
フィールドでグループ化し、個別の 値ごとにドキュメントの数を蓄積します
$pipeline = [ ['$match' => ['cuisine' => 'Bakery']], ['$group' => ['_id' => '$borough', 'count' => ['$sum' => 1]]], ]; $cursor = $collection->aggregate($pipeline); foreach ($cursor as $doc) { echo json_encode($doc), PHP_EOL; }
{"_id":"Brooklyn","count":173} {"_id":"Queens","count":204} {"_id":"Bronx","count":71} {"_id":"Staten Island","count":20} {"_id":"Missing","count":2} {"_id":"Manhattan","count":221}
集計の説明
MongoDBが操作を実行する方法に関する情報を表示するには、 MongoDBクエリ プランナーにそれを説明するように指示できます。 MongoDBが操作を説明すると、実行プランとパフォーマンス統計が返されます。 実行プランは、 MongoDBが操作を完了できる潜在的な方法です。 MongoDBに操作を説明するように指示すると、 MongoDBが実行したプランと拒否された実行プランの両方が返されます。
集計操作を説明するには、 MongoDB\Operation\Aggregate
オブジェクトを作成し、データベース、コレクション、パイプラインステージをパラメーターとして渡します。 次に、 MongoDB\Operation\Aggregate
オブジェクトをMongoDB\Collection::explain()
メソッドに渡します。
次の例では、 MongoDB に前のセクションの集計操作を説明するように指示します。
$pipeline = [ ['$match' => ['cuisine' => 'Bakery']], ['$group' => ['_id' => '$borough', 'count' => ['$sum' => 1]]], ]; $aggregate = new MongoDB\Operation\Aggregate( $collection->getDatabaseName(), $collection->getCollectionName(), $pipeline ); $result = $collection->explain($aggregate); echo json_encode($result), PHP_EOL;
{"explainVersion":"2","queryPlanner":{"namespace":"sample_restaurants.restaurants", "indexFilterSet":false,"parsedQuery":{"cuisine":{"$eq":"Bakery"}},"queryHash":"865F14C3", "planCacheKey":"D56D6F10","optimizedPipeline":true,"maxIndexedOrSolutionsReached":false, "maxIndexedAndSolutionsReached":false,"maxScansToExplodeReached":false,"winningPlan":{ ... }
集計ビルダー
集計ビルダ を使用して集計パイプラインを作成するには、次のアクションを実行します。
パイプラインステージを保存するには、
MongoDB\Builder\Pipeline
インスタンスを作成します。各ステージについて、目的の集計ステージと同じ名前を共有する
Stage
からファクトリー メソッドを呼び出します。例、$unwind
ステージを作成するには、Stage::unwind()
メソッドを呼び出します。Stage
メソッドの本体内で、Query
、Expression
、Accumulator
などの他のビルダ クラスのメソッドを使用して集計仕様をExpress。
次のコードは、集計パイプラインを構築するためのテンプレートを示しています。
$pipeline = new Pipeline( Stage::<factory method>( <stage specification> ), Stage::<factory method>( <stage specification> ), // ... ); $cursor = $collection->aggregate($pipeline);
このセクションの例は、MongoDB Serverマニュアルを使用しています。各例には、データベースに挿入して集計操作をテストできるサンプルデータへのリンクが記載されています。
フィルターとグループの例
この例では、サーバー マニュアルの $group
ステージ参照の 「カウント、合計、平均の計算」セクションに記載されているサンプルデータを使用します。
次のコード例では、2014 年 の各日の合計売上額、平均売上数量、売上件数を計算します。そのために、次のステージを含む集計パイプラインを使用します。
$match ステージ: 年が 2014 である
date
フィールドを含むドキュメントをフィルタリングしますドキュメントを日付別にグループ化し、各グループの合計売上額、平均売上数量、売上件数を計算する $group ステージ
$sort ステージ: 結果を各グループの合計売上額の降順でソートします
$pipeline = new MongoDB\Builder\Pipeline( MongoDB\Builder\Stage::match( date: [ MongoDB\Builder\Query::gte(new MongoDB\BSON\UTCDateTime(new DateTimeImmutable('2014-01-01'))), MongoDB\Builder\Query::lt(new MongoDB\BSON\UTCDateTime(new DateTimeImmutable('2015-01-01'))), ], ), MongoDB\Builder\Stage::group( _id: MongoDB\Builder\Expression::dateToString(MongoDB\Builder\Expression::dateFieldPath('date'), '%Y-%m-%d'), totalSaleAmount: MongoDB\Builder\Accumulator::sum( MongoDB\Builder\Expression::multiply( MongoDB\Builder\Expression::numberFieldPath('price'), MongoDB\Builder\Expression::numberFieldPath('quantity'), ), ), averageQuantity: MongoDB\Builder\Accumulator::avg( MongoDB\Builder\Expression::numberFieldPath('quantity'), ), count: MongoDB\Builder\Accumulator::sum(1), ), MongoDB\Builder\Stage::sort( totalSaleAmount: MongoDB\Builder\Type\Sort::Desc, ), ); $cursor = $collection->aggregate($pipeline); foreach ($cursor as $doc) { echo json_encode($doc), PHP_EOL; }
{"_id":"2014-04-04","totalSaleAmount":{"$numberDecimal":"200"},"averageQuantity":15,"count":2} {"_id":"2014-03-15","totalSaleAmount":{"$numberDecimal":"50"},"averageQuantity":10,"count":1} {"_id":"2014-03-01","totalSaleAmount":{"$numberDecimal":"40"},"averageQuantity":1.5,"count":2}
埋め込まれた配列の展開例
この例では、サーバー マニュアルの $unwind
ステージ参照の 「埋め込み配列の展開」セクションに記載されているサンプルデータを使用します。
次のコード例では、販売された商品をタグごとにグループ化し、タグごとに合計販売額を計算します。そのために、次のステージを含む集計パイプラインを使用します。
$unwind ステージ:
items
配列の要素ごとに個別のドキュメントを出力$unwind ステージ:
items.tags
配列の各要素に対して個別のドキュメントを出力します$group ステージ: ドキュメントをタグの値でグループ化し、各タグを持つアイテムの合計売上額を計算します。
$pipeline = new MongoDB\Builder\Pipeline( MongoDB\Builder\Stage::unwind(MongoDB\Builder\Expression::arrayFieldPath('items')), MongoDB\Builder\Stage::unwind(MongoDB\Builder\Expression::arrayFieldPath('items.tags')), MongoDB\Builder\Stage::group( _id: MongoDB\Builder\Expression::fieldPath('items.tags'), totalSalesAmount: MongoDB\Builder\Accumulator::sum( MongoDB\Builder\Expression::multiply( MongoDB\Builder\Expression::numberFieldPath('items.price'), MongoDB\Builder\Expression::numberFieldPath('items.quantity'), ), ), ), ); $cursor = $collection->aggregate($pipeline); foreach ($cursor as $doc) { echo json_encode($doc), PHP_EOL; }
{"_id":"office","totalSalesAmount":{"$numberDecimal":"1019.60"}} {"_id":"school","totalSalesAmount":{"$numberDecimal":"104.85"}} {"_id":"stationary","totalSalesAmount":{"$numberDecimal":"264.45"}} {"_id":"electronics","totalSalesAmount":{"$numberDecimal":"800.00"}} {"_id":"writing","totalSalesAmount":{"$numberDecimal":"60.00"}}
単一の等価結合の例
この例では、サーバー マニュアルの $lookup
ステージ参照の 「$lookup を使用して単一の等価結合を実行する」 セクションに記載されているサンプルデータを使用します。
次のコード例では、orders
コレクションの item
フィールドと inventory
コレクションの sku
フィールドを使用して、orders
コレクションのドキュメントと inventory
コレクションのドキュメントを結合します。
そのために、この例では、データを取得するコレクションとローカル フィールド名と外部フィールド名を指定する$lookupステージを含む集計パイプラインを使用します。
$pipeline = new MongoDB\Builder\Pipeline( MongoDB\Builder\Stage::lookup( from: 'inventory', localField: 'item', foreignField: 'sku', as: 'inventory_docs', ), ); /* Performs the aggregation on the orders collection */ $cursor = $collection->aggregate($pipeline); foreach ($cursor as $doc) { echo json_encode($doc), PHP_EOL; }
{"_id":1,"item":"almonds","price":12,"quantity":2,"inventory_docs":[{"_id":1,"sku":"almonds","description":"product 1","instock":120}]} {"_id":2,"item":"pecans","price":20,"quantity":1,"inventory_docs":[{"_id":4,"sku":"pecans","description":"product 4","instock":70}]} {"_id":3,"inventory_docs":[{"_id":5,"sku":null,"description":"Incomplete"},{"_id":6}]}
詳細情報
MongoDB PHPライブラリを使用して複雑な集計パイプラインを作成するチュートリアルについては、 MongoDB Developer Center の「 MongoDB Ops PHPとMongoDBを使用した複雑な集計パイプライン 」を参照してください。
集計ビルダを使用して構築された集計パイプラインのその他の例については、Github のPHPライブラリソースコードのステージクラステスト スイート を参照してください。
MongoDB Server マニュアル
このガイドで説明されているトピックについて詳しくは、 MongoDB Serverマニュアルの次のページ を参照してください。
式演算子の完全なリストを表示するには、「集計演算子 」を参照してください。
集計パイプラインの組み立てと例については、「集計パイプライン 」を参照してください。
パイプライン ステージの作成の詳細については、「集計ステージ 」を参照してください。
MongoDB 操作の説明の詳細については、「出力とクエリ プランの説明 」を参照してください。
Atlas Search とベクトル検索
Atlas Search 機能を使用して、全文検索を実行できます。詳しくは、「 Atlas Searchガイド 」を参照してください。
Atlas ベクトル検索機能を使用して、ベクトル埋め込みに対して類似性検索を実行できます。 詳細については、「 Atlas ベクトル検索ガイド 」を参照してください。
API ドキュメント
このガイドで説明されているメソッドの詳細については、次のAPIドキュメントを参照してください。