集計ビルダー
項目一覧
Overview
このガイドでは、Lambda 統合集計ビルダを使用して集計を実行し、パイプラインを構築する方法を学習できます。 集計ビルダーを使用すると、タイプセーフな構文を使用して MongoDB集計パイプラインを構築できます。
集計パイプラインとは、MongoDB database のデータに対して変換と計算を順番に実行し、その結果を新しいドキュメントまたはドキュメントのセットとして出力するデータ処理パイプラインです。
集計パイプラインは、集計ステージで構成されています。 集計ステージでは、演算子を使用して入力データを処理し、次のステージが入力として使用するデータを生成します。
Lambda MongoDB 集計ビルダを使用すると、集計ステージと集計パイプラインをビルドできます。 次のセクションでは、集計ビルダーを使用して集計パイプラインのステージを作成する方法の例を示します。
Tip
集計ビルダー機能は Lambda MongoDB バージョン4.3以降でのみ使用できます。 集計ビルダを使用せずに集計を実行する方法の詳細については、クエリ ビルダ ガイドの集計を参照してください。
集計ビルダの依存関係を追加する
集計ビルダは、 MongoDB /Builder パッケージの一部です。 このパッケージを使用するには、このパッケージを依存関係としてプロジェクトに追加する必要があります。 次のコマンドを実行して、集計ビルダーの依存関係をアプリケーションに追加します。
composer require mongodb/builder:^0.2
インストールが完了したら、 composer.json
ファイルのrequire
オブジェクトに次の行が含まれていることを確認します。
"mongodb/builder": "^0.2",
集計パイプラインを作成する
集計パイプラインを開始するには、 Model::aggregate()
メソッドを呼び出します。 次に、集計ステージのメソッドを実行する順序で連鎖させます。
集計ビルダーには、集計ステージを構築するためにインポートできる次の名前空間が含まれています。
MongoDB\Builder\Accumulator
MongoDB\Builder\Expression
MongoDB\Builder\Query
MongoDB\Builder\Type
Tip
ビルダ クラスの詳細については、 mongodb/mongodb-PHP-Builder を参照してください。 GitHubリポジトリ。
このセクションでは、一般的な集計ステージを使用し、ステージを組み合わせて集計パイプラインを構築する方法を示す次の例を紹介します。
MongoDB 集計演算子の詳細については、サーバー マニュアルの「集計ステージ」を参照してください。
サンプル ドキュメント
次の例では、 User
モデルで表されるコレクションに対して集計パイプラインを実行します。 次のinsert()
メソッドを実行してサンプル データを追加できます。
User::insert([ ['name' => 'Alda Gröndal', 'occupation' => 'engineer', 'birthday' => new UTCDateTime(new DateTimeImmutable('2002-01-01'))], ['name' => 'Francois Soma', 'occupation' => 'engineer', 'birthday' => new UTCDateTime(new DateTimeImmutable('1998-02-02'))], ['name' => 'Janet Doe', 'occupation' => 'designer', 'birthday' => new UTCDateTime(new DateTimeImmutable('1987-03-03'))], ['name' => 'Eliud Nkosana', 'occupation' => 'engineer', 'birthday' => new UTCDateTime(new DateTimeImmutable('1984-04-04'))], ['name' => 'Bran Steafan', 'occupation' => 'engineer', 'birthday' => new UTCDateTime(new DateTimeImmutable('1998-05-05'))], ['name' => 'Ellis Lee', 'occupation' => 'designer', 'birthday' => new UTCDateTime(new DateTimeImmutable('1996-06-06'))], ]);
マッチステージの例
クエリフィルターを指定するには、 match()
メソッドを集計パイプラインにチェーンできます。 このステージを省略すると、 aggregate()
メソッドは次の ステージのモデルの コレクション内のすべてのドキュメントを出力します。
この集計ステージは、利用可能なインデックスを使用してデータを取得し、後続のステージで処理されるデータ量を減らすために、多くの場合最初に配置されます。
Tip
match()
メソッドを省略すると、集計パイプラインは他の集計ステージの前のモデルに対応するコレクション内のすべてのドキュメントと一致します。
この例では、 MongoDB\Builder\Query
ビルダを使用して、一致集計ステージのクエリフィルターを構築します。 一致ステージには、次の条件が含まれます。
Query::or()
関数を使用して、クエリフィルターのいずれかに一致する結果を返しますoccupation
関数と 関数を使用して、値が である フィールドを含むドキュメントと一致させます"designer"
Query::query()
Query::eq()
name
関数と"Eliud Nkosana"
Query::query()
関数を使用して、 の値を持つ フィールドを含むドキュメントと一致させますQuery::eq()
コードの実行によって返されたドキュメントを確認するには、[ VIEW OUTPUTボタンをクリックします。
$pipeline = User::aggregate() ->match(Query::or( Query::query(occupation: Query::eq('designer')), Query::query(name: Query::eq('Eliud Nkosana')), )); $result = $pipeline->get();
[ { "_id": ..., "name": "Janet Doe", "occupation": "designer", "birthday": { "$date": { "$numberLong": "541728000000" } } }, { "_id": ..., "name": "Eliud Nkosana", "occupation": "engineer", "birthday": { "$date": { "$numberLong": "449884800000" } } }, { "_id": ..., "name": "Ellis Lee", "occupation": "designer", "birthday": { "$date": { "$numberLong": "834019200000" } } } ]
Tip
Query::or()
関数は、 $or
MongoDB クエリ演算子に対応します。 この演算子の詳細については、サーバー マニュアルの$orを参照してください。
グループ ステージの例
group()
メソッドを集計パイプラインにチェーンして、計算を実行し、一般的なフィールド値でグループ化してデータの構造を変更できます。
この集計ステージは、後続のステージで処理されるデータを減らすために、多くの場合、一致ステージの直後に配置されます。
この例では、 MongoDB\Builder\Expression
ビルダを使用して、グループ集計ステージでグループキーを定義します。 グループ ステージでは、次のグループ化動作を指定します。
_id
フィールドで表されるグループ キーの値を、Expression
ビルダで定義されたフィールド値に設定しますExpression::fieldPath()
関数を呼び出して、occupation
フィールドのドキュメント値を参照します
コードの実行によって返されたドキュメントを確認するには、[ VIEW OUTPUT ] ボタンをクリックします。
$pipeline = User::aggregate() ->group(_id: Expression::fieldPath('occupation')); $result = $pipeline->get();
[ { "_id": "engineer" }, { "_id": "designer" } ]
Tip
このサンプル ステージでは、 distinct()
クエリ ビルダ メソッドと同様のタスクを実行します。 distinct()
メソッドの詳細については、「個別のフィールド値の取得」の使用例を参照してください。
ソート ステージの例
ドキュメントの出力順序を指定するには、 sort()
メソッドを集計パイプラインにチェーンできます。
この集計ステージは、パイプラインのどこにでも追加できます。 グループ化されたデータに依存する可能性があるため、グループ ステージの後に配置されることが多い。 処理されるデータを制限するために、ソート ステージを可能な限りパイプラインの末尾に配置することをお勧めします。
並べ替えを指定するには、フィールド値を 昇順ソート の場合はSort::Asc
列挙型に設定し、降順ソートの場合はSort::Desc
列挙型に設定します。
この例では、ドキュメントをname
フィールドでSort::Desc
にソートするsort()
集計パイプライン ステージが示されています。これはアルファベットの逆順に対応します。 コードの実行によって返されたドキュメントを確認するには、 VIEW OUTPUTボタンをクリックします。
$pipeline = User::aggregate() ->sort(name: Sort::Desc); $result = $pipeline->get();
[ { "_id": ..., "name": "Janet Doe", "occupation": "designer", "birthday": { "$date": { "$numberLong": "541728000000" } } }, { "_id": ..., "name": "Francois Soma", "occupation": "engineer", "birthday": { "$date": { "$numberLong": "886377600000" } } }, { "_id": ..., "name": "Ellis Lee", "occupation": "designer", "birthday": { "$date": { "$numberLong": "834019200000" } } }, { "_id": ..., "name": "Eliud Nkosana", "occupation": "engineer", "birthday": { "$date": { "$numberLong": "449884800000" } } }, { "_id": ..., "name": "Bran Steafan", "occupation": "engineer", "birthday": { "$date": { "$numberLong": "894326400000" } } }, { "_id": ..., "name": "Alda Gröndal", "occupation": "engineer", "birthday": { "$date": { "$numberLong": "1009843200000" } } } ]
プロジェクト ステージの例
project()
メソッドを集計パイプラインにチェーンして、このステージで表示するドキュメントのフィールドを指定できます。
含めるフィールドを指定するには、フィールドの名前と1
やtrue
などの真実の値を渡します。 他のすべてのフィールドは出力から省略されます。
あるいは、除外するフィールドを指定するには、各フィールド名と誤った値( 0
やfalse
など)を渡します。 他のすべてのフィールドは出力に含まれます。
Tip
含めるフィールドを指定すると、 _id
フィールドがデフォルトで含まれます。 _id
フィールドを除外するには、プロジェクション ステージで明示的に除外します。
この例では、 project()
メソッド集計ステージを使用してname
フィールドのみを含め、他のすべてのフィールドを出力から除外する方法を示します。 コードの実行によって返されたデータを確認するには、 VIEW OUTPUTボタンをクリックします。
$pipeline = User::aggregate() ->project(_id: 0, name: 1); $result = $pipeline->get();
[ { "name": "Alda Gröndal" }, { "name": "Francois Soma" }, { "name": "Janet Doe" }, { "name": "Eliud Nkosana" }, { "name": "Bran Steafan" }, { "name": "Ellis Lee" } ]
aggregation pipelineの例
この集計パイプラインの例は、複数のステージに連結されています。 各ステージは、先行する各ステージから取得された出力に対して実行されます。 この例では、 ステージは次の操作を順番に実行します。
birth_year
フィールドをドキュメントに追加し、値をbirthday
フィールドから抽出された年に設定します。occupation
フィールドの値でドキュメントをグループ化し、Accumulator::avg()
関数を使用して各グループのbirth_year
の平均値を計算します。 計算の結果をbirth_year_avg
フィールドに割り当てます。ドキュメントをグループキー フィールドで昇順にソートします。
グループキー フィールドの値から
profession
フィールドを作成し、birth_year_avg
フィールドを含め、_id
フィールドを省略します。
コードの実行によって返されるデータを確認するには、[ VIEW OUTPUT ] ボタンをクリックします。
$pipeline = User::aggregate() ->addFields( birth_year: Expression::year( Expression::dateFieldPath('birthday'), ), ) ->group( _id: Expression::fieldPath('occupation'), birth_year_avg: Accumulator::avg(Expression::numberFieldPath('birth_year')), ) ->sort(_id: Sort::Asc) ->project(profession: Expression::fieldPath('_id'), birth_year_avg: 1, _id: 0);
[ { "birth_year_avg": 1991.5, "profession": "designer" }, { "birth_year_avg": 1995.5, "profession": "engineer" } ]
注意
このパイプラインはmatch()
ステージを省略するため、最初のステージの入力はコレクション内のすべてのドキュメントで構成されます。
カスタム演算子ファクトリを作成する
集計ビルダー を使用して集計パイプラインを作成する場合、カスタム演算子ファクトリーで操作またはステージを定義できます。 カスタム演算子ファクトリーは、 集計パイプライン の式またはステージを返す関数です。 これらの関数を作成すると、コードの読みやすさと再利用を向上させることができます。
この例では、指定された日付フィールドから年を抽出する式を返すカスタム演算子ファクトリを作成して使用する方法を示します。
次の関数は、日付を含むフィールドの名前を受け入れ、日付から年を抽出する式を返します。
public function yearFromField(string $dateFieldName): YearOperator { return Expression::year( Expression::dateFieldPath($dateFieldName), ); }
サンプル集計パイプラインには、次のステージが含まれています。
addFields()
は、カスタム演算子ファクトリー関数を呼び出して、birthday
フィールドから年を抽出し、それをbirth_year
フィールドに割り当てます。project()
は、出力にname
birth_year
フィールドと フィールドのみを含みます。
コードの実行によって返されるデータを確認するには、[ VIEW OUTPUT ] ボタンをクリックします。
$pipeline = User::aggregate() ->addFields(birth_year: $this->yearFromField('birthday')) ->project(_id: 0, name: 1, birth_year: 1);
[ { "name": "Alda Gröndal", "birth_year": 2002 }, { "name": "Francois Soma", "birth_year": 1998 }, { "name": "Janet Doe", "birth_year": 1987 }, { "name": "Eliud Nkosana", "birth_year": 1984 }, { "name": "Bran Steafan", "birth_year": 1998 }, { "name": "Ellis Lee", "birth_year": 1996 } ]