db.collection.aggregate()
MongoDB とドライバー
このページでは、 mongosh
メソッドについて説明します。MongoDB ドライバーで同等のメソッドを確認するには、ご使用のプログラミング言語の対応するページを参照してください。
定義
db.collection.aggregate(pipeline, options)
コレクションまたはビュー内のデータの集計値を計算します。
次の値を返します。
互換性
次の環境でホストされる配置には db.collection.aggregate()
を使用できます。
MongoDB Atlas はクラウドでの MongoDB 配置のためのフルマネージド サービスです
MongoDB Enterprise: サブスクリプションベースの自己管理型 MongoDB バージョン
MongoDB Community: ソースが利用可能で、無料で使用できる自己管理型の MongoDB のバージョン
構文
aggregate()
メソッドの形式は次のとおりです。
db.collection.aggregate( <pipeline>, <options> )
aggregate()
メソッドは次のパラメーターを取ります。
Parameter | タイプ | 説明 |
---|---|---|
pipeline | 配列 | データ集計の一連の操作またはステージ。 詳細については、集計パイプライン演算子を参照してください。 このメソッドでは、配列の要素としてではなく、個別の引数としてパイプライン ステージを受け入れ可能ですが、 |
options | ドキュメント |
options
ドキュメントには、次のフィールドと値を含めることができます。
バージョン 5.0 での変更。
フィールド | タイプ | 説明 | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
explain | ブール値 | 任意。 パイプラインの処理に関する情報を返すように指定します。 例については、 「 集計パイプライン操作に関する情報の返却」を参照してください。 マルチドキュメントトランザクションでは使用できません。 | ||||||||||
allowDiskUse | ブール値 | 任意。 一時ファイルへの書込みを有効にします。 プロファイラー ログ メッセージと診断ログ メッセージには、メモリ制限のために集計ステージで一時ファイルにデータが書込まれた場合、 | ||||||||||
cursor | ドキュメント | 任意。カーソルの初期バッチ サイズを指定します。 cursor フィールドの値は、フィールド batchSize が含まれるドキュメントです。構文と例については、「初期バッチ サイズの指定」を参照してください。 | ||||||||||
maxTimeMS | non-negative integer | 任意。カーソルに対する情報処理操作の時間制限をミリ秒単位で指定します。maxTimeMS の値を指定しない場合、操作はタイムアウトしません。値を MongoDB は、 | ||||||||||
bypassDocumentValidation | ブール値 | 任意。 操作中に バージョン 3.2 で追加。 | ||||||||||
readConcern | ドキュメント | 任意。読み取り保証 (read concern) を指定します。
次の読み取り保証レベルが利用できます。
読み取り保証 (read concern) のレベルについて詳しくは、「読み取り保証 (read concern) レベル」を参照してください。
| ||||||||||
ドキュメント | 任意。 操作に使用する照合を指定します。 照合を指定すると、大文字・小文字やアクセント記号など、文字列を比較するための言語独自のルールを指定できます。 照合オプションの構文は次のとおりです。
照合を指定する場合、 照合が指定されていなくても、コレクションにデフォルトの照合が設定されている場合( コレクションにも操作にも照合が指定されていない場合、MongoDB では以前のバージョンで使用されていた単純なバイナリ比較によって文字列が比較されます。 1 つの操作に複数の照合は指定できません。たとえば、フィールドごとに異なる照合を指定できません。また、ソートと検索を一度に実行する場合、検索とソートで別の照合を使用できません。 バージョン 3.4 で追加。 | |||||||||||
hint | 文字列またはドキュメント | 任意。集計に使用するインデックス。インデックスは、集計が実行される最初のコレクションまたはビューにあります。 インデックス名、またはインデックス仕様ドキュメントのいずれかによってインデックスを指定します。 注意
バージョン 3.6 の新機能。 | ||||||||||
comment | string | 任意。データベースプロファイラ、currentOp、およびログから操作を追跡するのに役立つ任意の文字列を指定できます。 バージョン 3.6 の新機能。 | ||||||||||
writeConcern | ドキュメント | 任意。または | ||||||||||
let | ドキュメント | 任意。 変数のリストを含むドキュメントを指定します。これにより、変数をクエリテキストから分離することで、コマンドの読みやすさを向上させることができます。 ドキュメントの構文は次のとおりです。
変数は式によって返された値に設定され、その後は変更できません。 コマンド内の変数の値にアクセスするには、二重ドル記号の接頭辞( パイプライン
バージョン 5.0 で追加 |
動作
Error Handling
エラーが発生した場合、aggregate()
ヘルパーは例外をスローします。
カーソルの動作
mongosh
では、 db.collection.aggregate()
から返されたカーソルがvar
キーワードを使用して変数に割り当てられていない場合、 mongosh
は最大20回までカーソルを自動的に反復します。 mongosh
でのカーソルの処理については、「 でのカーソルの反復mongosh
」を参照してください。
集計から返されるカーソルは、評価済みカーソル(最初のバッチが取得されたカーソル)で動作する次のようなカーソル メソッドのみをサポートします。
セッション
セッション内で作成されたカーソルの場合、セッション外で getMore
を呼び出すことはできません。
同様に、セッション外で作成されたカーソルの場合、セッション内で getMore
を呼び出すことはできません。
セッション アイドル タイムアウト
MongoDB ドライバーとmongosh
では、確認されていない書込み操作を除くすべての操作がサーバー セッションに関連付けられます。セッションに明示的に関連付けられていない操作(つまり Mongo.startSession()
を使用するもの)の場合、MongoDB ドライバーとmongosh
によって暗黙的なセッションが作成され、それが操作に関連付けられます。
セッションが30分以上アイドル状態になると、MongoDBサーバーはそのセッションを期限切れとしてマークし、いつでも閉じる可能性があります。MongoDB サーバーでセッションが閉じると、そのセッションで進行中の操作や開いているカーソルもすべて終了します。これには、noCursorTimeout()
や 30 分を超える maxTimeMS()
で構成されたカーソルも含まれます。
カーソルを返す操作の場合、カーソルが 30 分以上アイドル状態になる可能性がある場合は、 Mongo.startSession()
を使用して明示的なセッション内で操作を発行し、 refreshSessions
コマンドを使用して定期的にセッションを更新します。詳細については、セッションアイドルタイムアウトを参照してください。
トランザクション
db.collection.aggregate()
は分散トランザクション内で使用できます。
ただし、トランザクション内では以下のステージは許可されません。
また、explain
オプションも指定できません。
トランザクションの外部で作成されたカーソルの場合、トランザクション内で
getMore
を呼び出せません。トランザクション内で作成されたカーソルの場合、トランザクション外で
getMore
を呼び出せません。
重要
ほとんどの場合、分散トランザクションでは 1 つのドキュメントの書き込み (write) よりもパフォーマンス コストが高くなります。分散トランザクションの可用性は、効果的なスキーマ設計の代わりにはなりません。多くのシナリオにおいて、非正規化されたデータモデル(埋め込みドキュメントと配列)が引き続きデータやユースケースに最適です。つまり、多くのシナリオにおいて、データを適切にモデリングすることで、分散トランザクションの必要性を最小限に抑えることができます。
トランザクションの使用に関するその他の考慮事項(ランタイム制限や oplog サイズ制限など)については、「本番環境での考慮事項」も参照してください。
クライアントの切断
$out
ステージまたは $merge
ステージを含まない db.collection.aggregate()
操作の場合。
MongoDB 4.2以降では、 db.collection.aggregate()
を発行したクライアントが操作の完了前に切断した場合、MongoDB は killOp
を使用してdb.collection.aggregate()
を終了対象としてマークし 。
例
以下の例では、次のドキュメントを含むコレクション orders
を使用します。
db.orders.insertMany( [ { _id: 1, cust_id: "abc1", ord_date: ISODate("2012-11-02T17:04:11.102Z"), status: "A", amount: 50 }, { _id: 2, cust_id: "xyz1", ord_date: ISODate("2013-10-01T17:04:11.102Z"), status: "A", amount: 100 }, { _id: 3, cust_id: "xyz1", ord_date: ISODate("2013-10-12T17:04:11.102Z"), status: "D", amount: 25 }, { _id: 4, cust_id: "xyz1", ord_date: ISODate("2013-10-11T17:04:11.102Z"), status: "D", amount: 125 }, { _id: 5, cust_id: "abc1", ord_date: ISODate("2013-11-12T17:04:11.102Z"), status: "A", amount: 25 } ] )
グループ化と合計の計算
次の集計操作では、ステータスが "A"
と等しいドキュメントを選択し、一致するドキュメントをcust_id
フィールドでループ化し、amount
フィールドの合計から各cust_id
フィールドの total
を計算し、結果をtotal
フィールドで降順にソートします。
db.orders.aggregate( [ { $match: { status: "A" } }, { $group: { _id: "$cust_id", total: { $sum: "$amount" } } }, { $sort: { total: -1 } } ] )
この操作は、次のドキュメントを持つカーソルを返します。
[ { _id: "xyz1", total: 100 }, { _id: "abc1", total: 75 } ]
mongosh
は返されたカーソルを自動的に反復して結果を出力します。mongosh
でカーソルを手動で取り扱うには、「mongosh
でのカーソルの反復」を参照してください。
集計パイプライン操作に関する情報を返します。
次の例では、db.collection.explain()
を使用して、集計パイプラインの実行プランに関する詳細情報を表示します。
db.orders.explain().aggregate( [ { $match: { status: "A" } }, { $group: { _id: "$cust_id", total: { $sum: "$amount" } } }, { $sort: { total: -1 } } ] )
この操作は集計パイプラインの処理を詳述するドキュメントを返します。たとえば、このドキュメントにはどのインデックスが操作に使用されたかなどの詳細が示されます。[1] orders
コレクションがシャーディングされたコレクションの場合は、シャード間の作業分担やマージ操作、ターゲットクエリの場合にはターゲットシャードもドキュメントに表示されます。
注意
explain
出力ドキュメントの対象読者は機械ではなく人間であり、出力形式はリリース間で変更される可能性があります。
executionStats
または allPlansExecution
説明モードを db.collection.explain()
メソッドに渡すと、より冗長な説明出力を表示できます。
[1] | インデックス フィルターは使用インデックスの選択に影響する可能性があります。詳細については、「インデックス フィルター」を参照してください。 |
外部ソートによる大規模なソート操作の実行
個々のパイプライン ステージのそれぞれには、 100メガバイトの RAM 制限があります。 デフォルトでは、 ステージがこの制限を超えると、MongoDB はエラーを発生させます。 パイプライン処理がより多くのスペースを使用できるようにするには、次の例のように、 allowDiskUseオプションをtrue
に設定して、一時ファイルへのデータの書き込みを有効にします。
var results = db.stocks.aggregate( [ { $sort : { cusip : 1, date: 1 } } ], { allowDiskUse: true } )
プロファイラー ログ メッセージと診断ログ メッセージには、メモリ制限のために集計ステージで一時ファイルにデータが書込まれた場合、usedDisk
インジケーターが含められます。
初期バッチ サイズの指定
カーソルの初期バッチ サイズを指定するには、cursor
オプションに次の構文を使用します。
cursor: { batchSize: <int> }
たとえば、次の集計操作では、カーソルの初期バッチサイズとして 0
を指定します。
db.orders.aggregate( [ { $match: { status: "A" } }, { $group: { _id: "$cust_id", total: { $sum: "$amount" } } }, { $sort: { total: -1 } }, { $limit: 2 } ], { cursor: { batchSize: 0 } } )
初期バッチのサイズを指定する { cursor: { batchSize: 0 } }
ドキュメントは、1 個めのバッチが空であることを示します。このバッチサイズは、サーバー側での目立った作業なしに、カーソルやエラーメッセージをすばやく返すのに便利です。
後続の getMore
操作(最初のバッチの後)のバッチ サイズを指定するには、getMore
コマンドを実行する際に batchSize
フィールドを使用します。
mongosh
は返されたカーソルを自動的に反復して結果を出力します。mongosh
でカーソルを手動で取り扱うには、「mongosh
でのカーソルの反復」を参照してください。
照合の指定
バージョン 3.4 で追加。
照合を指定すると、大文字・小文字やアクセント記号など、文字列を比較するための言語独自のルールを指定できます。
コレクション restaurants
は、次のドキュメントを含みます。
db.restaurants.insertMany( [ { _id: 1, category: "café", status: "A" }, { _id: 2, category: "cafe", status: "a" }, { _id: 3, category: "cafE", status: "a" } ] )
次の集計操作には 照合オプションが含まれます。
db.restaurants.aggregate( [ { $match: { status: "A" } }, { $group: { _id: "$category", count: { $sum: 1 } } } ], { collation: { locale: "fr", strength: 1 } } );
注意
複数のビューが関わる集計($lookup
や $graphLookup
など)が実行される場合、それらのビューには同じ照合が含まれる必要があります。
照合フィールドの説明については、照合ドキュメントを参照してください。
インデックスの hint
次のドキュメントを使用してコレクション food
を作成します。
db.food.insertMany( [ { _id: 1, category: "cake", type: "chocolate", qty: 10 }, { _id: 2, category: "cake", type: "ice cream", qty: 25 }, { _id: 3, category: "pie", type: "boston cream", qty: 20 }, { _id: 4, category: "pie", type: "blueberry", qty: 15 } ] )
下記のインデックスを作成します。
db.food.createIndex( { qty: 1, type: 1 } ); db.food.createIndex( { qty: 1, category: 1 } );
下記の集計操作には、指定されたインデックスの使用を強制する hint
オプションが含まれています。
db.food.aggregate( [ { $sort: { qty: 1 }}, { $match: { category: "cake", qty: 10 } }, { $sort: { type: -1 } } ], { hint: { qty: 1, category: 1 } } )
[readConcern] の上書き readConcern
操作の読み取り保証(read concern)を指定するには、readConcern
オプションを使用します。
$out
または $merge
ステージは、読み取り保証 "linearizable"
と組み合わせて使用できません。そのため、"linearizable"
の読み取り保証を db.collection.aggregate()
に対して指定した場合、いずれのステージもパイプラインに含めることはできません。
レプリカセットに対する次の操作では、大多数のノードに書き込まれたことが確認されたデータの最新のコピーを読み取るために、"majority"
の 読み取り保証を指定します。
注意
単一のスレッドでそれ自体の書き込みの読み取りを可能にするには、レプリカセットのプライマリに対して
"majority"
読み取り保証と"majority"
書込み保証を使用します。$out
ステージを含む集計に対して、読み取り保証レベル"majority"
を指定できます。読み取り保証のレベルを問わず、ノード上の最新データにシステム内のデータの最新バージョンが反映されていない場合があります。
db.restaurants.aggregate( [ { $match: { rating: { $lt: 5 } } } ], { readConcern: { level: "majority" } } )
コメントの指定
コレクション「movies
」には次のような形式のドキュメントが含まれています。
db.movies.insertOne( { _id: ObjectId("599b3b54b8ffff5d1cd323d8"), title: "Jaws", year: 1975, imdb: "tt0073195" } )
次の集計操作では、1995 年に制作された映画が検索し、comment
オプションを含めて、logs
、db.system.profile
コレクション、およびdb.currentOp
内の追跡情報を提供します。
db.movies.aggregate( [ { $match: { year : 1995 } } ], { comment : "match_all_movies_from_1995" } ).pretty()
プロファイリングが有効になっているシステムでは、以下で示すように、system.profile
コレクションにクエリを実行して、すべての最新の類似した集計を確認できます。
db.system.profile.find( { "command.aggregate": "movies", "command.comment" : "match_all_movies_from_1995" } ).sort( { ts : -1 } ).pretty()
このクエリでは、プロファイラーの結果セットが次の形式で返されます。
{ "op" : "command", "ns" : "video.movies", "command" : { "aggregate" : "movies", "pipeline" : [ { "$match" : { "year" : 1995 } } ], "comment" : "match_all_movies_from_1995", "cursor" : { }, "$db" : "video" }, ... }
アプリケーションは、システム内の特定の操作をより簡単に追跡または識別できるように、コメントに任意の情報をエンコードできます。たとえば、プロセス ID、スレッド ID、クライアントのホスト名、コマンドを発行したユーザーを含む文字列コメントを添付できます。
変数の使用 let
バージョン 5.0 で追加
コマンド内の他の場所からアクセスできる変数を定義するには let オプションを使用します。
さまざまなフレーバーのケーキの売上情報を含むコレクション cakeSales
を作成するとします。
db.cakeSales.insertMany( [ { _id: 1, flavor: "chocolate", salesTotal: 1580 }, { _id: 2, flavor: "strawberry", salesTotal: 4350 }, { _id: 3, flavor: "cherry", salesTotal: 2150 } ] )
次の例:
salesTotal
が3000より大きいケーキ、つまり_id
が 2 のケーキを検索します。let
でtargetTotal
変数を定義します。これは$gt
で$$targetTotal
として参照されます。
db.cakeSales.aggregate( [ { $match: { $expr: { $gt: [ "$salesTotal", "$$targetTotal" ] } } } ], { let: { targetTotal: 3000 } } )