Docs Menu
Docs Home
/
MongoDBマニュアル
/ / /

集計

項目一覧

  • 定義
  • 互換性
  • 構文
  • セッション
  • トランザクション
  • クエリ設定
  • Stable API
aggregate

集計パイプラインを使用して集計操作を実行します。 パイプラインを使用すると、ユーザーはコレクションやその他のソースからのデータをステージベース操作のシークエンスで処理できます。

Tip

mongosh では、このコマンドは db.aggregate() ヘルパー メソッドおよび db.collection.aggregate() ヘルパー メソッドで実行できます。または watch() ヘルパー メソッドを使用することも可能です。

ヘルパー メソッドはmongoshユーザーには便利ですが、データベースコマンドと同じレベルの情報は返されない可能性があります。 便宜上必要ない場合、または追加の戻りフィールドが必要な場合は、 データベースコマンドを使用します。

このコマンドは、次の環境でホストされている配置で使用できます。

  • MongoDB Atlas はクラウドでの MongoDB 配置のためのフルマネージド サービスです

重要

このコマンドは、M 0 、M 2 、および M 5クラスターで限定的にサポートされています。 詳細については、「サポートされていないコマンド 」を参照してください。

  • MongoDB Enterprise: サブスクリプションベースの自己管理型 MongoDB バージョン

  • MongoDB Community: ソースが利用可能で、無料で使用できる自己管理型の MongoDB のバージョン

バージョン 5.0 での変更

このコマンドの構文は、次のとおりです。

db.runCommand(
{
aggregate: "<collection>" || 1,
pipeline: [ <stage>, <...> ],
explain: <boolean>,
allowDiskUse: <boolean>,
cursor: <document>,
maxTimeMS: <int>,
bypassDocumentValidation: <boolean>,
readConcern: <document>,
collation: <document>,
hint: <string or document>,
comment: <any>,
writeConcern: <document>,
let: <document> // Added in MongoDB 5.0
}
)

aggregate コマンドは、次のフィールドを引数として受け取ります。

フィールド
タイプ
説明
aggregate
string
集約パイプラインへの入力となるコレクションまたはビューの名前。コレクションに依存しないコマンドには 1 を使用します。
pipeline
配列
集計パイプラインの一部としてドキュメントストリームを処理および変換する集計パイプライン ステージの配列。
explain
ブール値

任意。パイプラインの処理に関する情報を返すように指定します。

マルチドキュメントトランザクションでは使用できません。

allowDiskUse

ブール値

任意。

このオプションを使用して、特定のクエリの allowDiskUseByDefault をオーバーライドできます。このオプションは下記のいずれかに使用できます。

  • デフォルトでディスクの使用が許可されているシステムで、ディスクの使用を禁止する。

  • デフォルトでディスクの使用が禁止されているシステムで、ディスクの使用を許可する。

MongoDB 6.0 以降では、 allowDiskUseByDefaulttrue に設定されており、かつパイプライン実行ステージのために 100 MB を超えるメモリがサーバーに必要な場合、クエリで { allowDiskUse: false } が指定されていない限り、MongoDB では一時ファイルが自動的にディスクに書き込まれます。

詳細については、allowDiskUseByDefault を参照してください。

プロファイラー ログ メッセージ診断ログ メッセージには、メモリ制限のために集計ステージで一時ファイルにデータが書込まれた場合、usedDisk インジケーターが含められます。

cursor
ドキュメント

カーソルオブジェクト作成を制御するオプションを含めたドキュメントを指定。

MongoDB は、aggregate コマンドが explain オプションを含まない場合は、cursor オプションを含まないこのコマンドの使用を削除します。explain オプションを含まない場合は、カーソル オプションを指定する必要があります。

  • デフォルトのバッチ サイズのカーソルを示すには、cursor: {} を指定します。

  • デフォルト以外のバッチ サイズのカーソルを示すには、cursor: { batchSize: <num> } を使用します。

maxTimeMS
non-negative integer

任意。

時間制限をミリ秒単位で指定します。maxTimeMS の値を指定しない場合、操作はタイムアウトしません。値を 0 にすると、デフォルトの無制限動作を明示的に指定します。

MongoDB は、db.killOp() と同じメカニズムを使用して、割り当てられた時間制限を超えた操作を終了します。MongoDB は、指定された割り込みポイントのいずれかでのみ操作を終了します。

bypassDocumentValidation
ブール値

任意。$outまたは $merge 集計ステージを指定した場合にのみ該当します。

操作中にaggregateがドキュメント検証をバイパスできるようにします。 これにより、検証要件を満たさないドキュメントを挿入できるようになります。

readConcern
ドキュメント

任意。読み取り保証 (read concern) を指定します。

readConcern オプションの構文は、次のとおりです。readConcern: { level: <value> }

次の読み取り保証レベルが利用できます。

  • "local"。これは、プライマリとセカンダリに対する読み取り操作での、デフォルトの読み取り保証レベルです。

  • "available" 。プライマリおよびセカンダリに対する読み取り操作に使用できます。"available" は、プライマリおよびシャーディングされていないセカンダリに対して "local" と同じように動作します。クエリは、インスタンスの最新データを返します。

  • "majority"WiredTiger ストレージ エンジンを使用するレプリカセットで使用できます。

  • "linearizable"primary の読み取り操作にのみ使用できます。

読み取り保証 (read concern) のレベルについて詳しくは、「読み取り保証 (read concern) レベル」を参照してください。

$out ステージは読み取り保証 (read concern) "linearizable" と組み合わせて使用することはできません。db.collection.aggregate() に対して "linearizable" 読み取り保証 (read concern) を指定した場合、パイプライン内に $out ステージを含めることはできません。

$mergeステージは読み取り保証(read concern)"linearizable"と組み合わせて使用することはできません。つまり、db.collection.aggregate()に対して読み取り保証(read concern)"linearizable"を指定した場合、パイプラインに$mergeステージを含めることはできません。

collation
ドキュメント

任意。

操作に使用する照合を指定します。

照合を指定すると、大文字・小文字やアクセント記号など、文字列を比較するための言語独自のルールを指定できます。

照合オプションの構文は次のとおりです。

collation: {
locale: <string>,
caseLevel: <boolean>,
caseFirst: <string>,
strength: <int>,
numericOrdering: <boolean>,
alternate: <string>,
maxVariable: <string>,
backwards: <boolean>
}

照合を指定する場合、locale フィールドは必須ですが、その他の照合フィールドはすべて任意です。フィールドの説明については、照合ドキュメントを参照してください。

照合が指定されていなくても、コレクションにデフォルトの照合が設定されている場合(db.createCollection() を参照)には、コレクションの照合が使用されます。

コレクションにも操作にも照合が指定されていない場合、MongoDB では以前のバージョンで使用されていた単純なバイナリ比較によって文字列が比較されます。

1 つの操作に複数の照合は指定できません。たとえば、フィールドごとに異なる照合を指定できません。また、ソートと検索を一度に実行する場合、検索とソートで別の照合を使用できません。

hint
文字列またはドキュメント

任意。集計に使用するインデックス。インデックスは、集計が実行される最初のコレクションまたはビューにあります。

インデックス名、またはインデックス仕様ドキュメントのいずれかによってインデックスを指定します。

hint$lookup および$graphLookup ステージには適用されません。

comment
any

任意。このコマンドに添付するユーザー指定のコメント。設定すると、このコメントは以下の場所にこのコマンドの記録と合わせて表示されます。

コメントには、有効な BSON 型(string, integer, object, array など)を使用できます。

aggregate コマンドに設定されたコメントは、aggregate カーソルで実行される後続の getMore コマンドに継承されます。

writeConcern
ドキュメント

任意。または $out$mergeステージで使用する 書き込みの考慮事項 を表すドキュメント。

$out または $merge ステージでデフォルトの書き込み保証を使用しません。

let
ドキュメント

任意。

変数のリストを含むドキュメントを指定します。これにより、変数をクエリテキストから分離することで、コマンドの読みやすさを向上させることができます。

ドキュメントの構文は次のとおりです。

{
<variable_name_1>: <expression_1>,
...,
<variable_name_n>: <expression_n>
}

変数は式によって返された値に設定され、その後は変更できません。

コマンド内の変数の値にアクセスするには、二重ドル記号の接頭辞($$)を $$<variable_name> 形式にした変数名とともに使用します。たとえば次のとおりです。$$targetTotal

パイプライン $match ステージで変数を使用して結果をフィルター処理するには、$exprオペレーター内で変数にアクセスする必要があります。

let と変数を使用した完全な例については、「let における変数の使用」を参照してください。

バージョン 5.0 で追加

MongoDB は、aggregate コマンドが explain オプションを含まない場合は、cursor オプションを含まないこのコマンドの使用を削除します。explain オプションを含まない場合は、カーソル オプションを指定する必要があります。

  • デフォルトのバッチ サイズのカーソルを示すには、cursor: {} を指定します。

  • デフォルト以外のバッチ サイズのカーソルを示すには、cursor: { batchSize: <num> } を使用します。

集計パイプラインの詳細については、以下を参照してください。

セッション内で作成されたカーソルの場合、セッション外で getMore を呼び出すことはできません。

同様に、セッション外で作成されたカーソルの場合、セッション内で getMore を呼び出すことはできません。

MongoDB ドライバーとmongosh では、確認されていない書込み操作を除くすべての操作がサーバー セッションに関連付けられます。セッションに明示的に関連付けられていない操作(つまり Mongo.startSession()を使用するもの)の場合、MongoDB ドライバーとmongoshによって暗黙的なセッションが作成され、それが操作に関連付けられます。

セッションが30分以上アイドル状態になると、MongoDBサーバーはそのセッションを期限切れとしてマークし、いつでも閉じる可能性があります。MongoDB サーバーでセッションが閉じると、そのセッションで進行中の操作や開いているカーソルもすべて終了します。これには、noCursorTimeout() や 30 分を超える maxTimeMS() で構成されたカーソルも含まれます。

カーソルを返す操作の場合、カーソルが 30 分以上アイドル状態になる可能性がある場合は、 Mongo.startSession() を使用して明示的なセッション内で操作を発行し、 refreshSessions コマンドを使用して定期的にセッションを更新します。詳細については、セッションアイドルタイムアウトを参照してください。

aggregate分散トランザクション内で使用できます。

ただし、トランザクション内では以下のステージは許可されません。

また、explain オプションも指定できません。

  • トランザクションの外部で作成されたカーソルの場合、トランザクション内で getMore を呼び出せません。

  • トランザクション内で作成されたカーソルの場合、トランザクション外で getMore を呼び出せません。

重要

ほとんどの場合、分散トランザクションでは 1 つのドキュメントの書き込み (write) よりもパフォーマンス コストが高くなります。分散トランザクションの可用性は、効果的なスキーマ設計の代わりにはなりません。多くのシナリオにおいて、非正規化されたデータモデル(埋め込みドキュメントと配列)が引き続きデータやユースケースに最適です。つまり、多くのシナリオにおいて、データを適切にモデリングすることで、分散トランザクションの必要性を最小限に抑えることができます。

トランザクションの使用に関するその他の考慮事項(ランタイム制限や oplog サイズ制限など)については、「本番環境での考慮事項」も参照してください。

$out ステージまたは $merge ステージを含まない aggregate 操作の場合。

MongoDB 4.2以降では、 aggregateを発行したクライアントが操作の完了前に切断した場合、MongoDB は killOp を使用してaggregateを終了対象としてマークし

バージョン8.0の新機能

クエリ設定を使用して、インデックスヒント、操作拒否フィルター、その他のフィールドを設定できます。設定はクラスター全体のクエリシェイプに適用されます。クラスターは、シャットダウン後も設定を保持します。

クエリオプティマイザは、クエリプランニング中の追加入力としてクエリ設定を使用します。これは、クエリを実行するために選択されたプランに影響します。クエリ設定を使用してクエリシェイプをブロックすることもできます。

クエリ設定を追加して例を調べるには、setQuerySettings を参照してください。

finddistinct、および aggregate コマンドのクエリ設定を追加できます。

クエリ設定にはより多くの機能があり、廃止されたインデックスフィルターよりも優先されます。

クエリ設定を削除するには、 removeQuerySettingsを使用します。 クエリ設定を取得するには、集計パイプラインの$querySettingsステージを使用します。

Stable API V1 を使用する場合

MongoDB は、aggregate コマンドが explain オプションを含まない場合は、cursor オプションを含まないこのコマンドの使用を削除します。explain オプションを含まない場合は、カーソル オプションを指定する必要があります。

  • デフォルトのバッチ サイズのカーソルを示すには、cursor: {} を指定します。

  • デフォルト以外のバッチ サイズのカーソルを示すには、cursor: { batchSize: <num> } を使用します。

aggregate コマンドを直接実行するのではなく、むしろほとんどのユーザーは mongosh で提供される db.collection.aggregate() ヘルパーまたはドライバー内の同等のヘルパーを使用する必要があります。2.6 以降では db.collection.aggregate() ヘルパーは常にカーソルを返します。

コマンド構文を示す最初の 2 つの例を除き、このページの例では db.collection.aggregate() ヘルパーを使用します。

コレクション articles には次のドキュメントが含まれています。

{
_id: ObjectId("52769ea0f3dc6ead47c9a1b2"),
author: "abc123",
title: "zzz",
tags: [ "programming", "database", "mongodb" ]
}

次の例では articles コレクションに aggregate 操作を実行し、コレクション内に表示される tags 配列内の各個別要素の数を計算します。

db.runCommand( {
aggregate: "articles",
pipeline: [
{ $project: { tags: 1 } },
{ $unwind: "$tags" },
{ $group: { _id: "$tags", count: { $sum : 1 } } }
],
cursor: { }
} )

mongoshでは、この操作は次のように db.collection.aggregate() ヘルパーを使用できます。

db.articles.aggregate( [
{ $project: { tags: 1 } },
{ $unwind: "$tags" },
{ $group: { _id: "$tags", count: { $sum : 1 } } }
] )

次の例では、管理データベースで 2 つのステージを持つパイプラインを実行します。最初のステージでは $currentOp 操作を実行し、2 番目のステージではその操作の結果をフィルタリングします。

db.adminCommand( {
aggregate : 1,
pipeline : [ {
$currentOp : { allUsers : true, idleConnections : true } }, {
$match : { shard : "shard01" }
}
],
cursor : { }
} )

注意

aggregate コマンドはコレクションを指定せず、代わりに {aggregate: 1} の形式を取ります。これは、最初の $currentOp ステージではコレクションから入力が取得されないためです。パイプラインの残りの部分で使用される独自のデータを生成します。

こうしたコレクションレス集計の実行を支援するために、新しい db.aggregate() ヘルパーが追加されました。上の集計はこの例のように実行することもできます。

次の集計操作では、任意フィールド explaintrue に設定して、集計操作に関する情報を返します。

db.orders.aggregate([
{ $match: { status: "A" } },
{ $group: { _id: "$cust_id", total: { $sum: "$amount" } } },
{ $sort: { total: -1 } }
],
{ explain: true }
)

注意

explain の出力は、リリース間で変更される可能性があります。

Tip

以下も参照してください。

MongoDB 6.0 以降、 100 MB 以上のメモリを必要とするパイプライン ステージでは、デフォルトで一時ファイルをディスクに書き込みます。これらの一時ファイルはパイプラインの実行中ずっと残り、インスタンスのストレージ容量に影響を与える可能性があります。以前のバージョンの MongoDB では、この動作を有効にするには、個々の find コマンドと aggregate コマンドに { allowDiskUse: true } を渡す必要がありました。

個々の findaggregate コマンドは、次のいずれかの方法で allowDiskUseByDefault パラメーターを上書きできます。

  • allowDiskUseByDefaultfalse に設定されている場合に { allowDiskUse: true } を使用して一時ファイルをディスクに書き込むことを許可する

  • allowDiskUseByDefaulttrue に設定されている場合に { allowDiskUse: false } を使用して一時ファイルがディスクに書き込むことを禁止する

プロファイラー ログ メッセージ診断ログ メッセージには、メモリ制限のために集計ステージで一時ファイルにデータが書込まれた場合、usedDisk インジケーターが含められます。

Tip

以下も参照してください。

初期バッチサイズを指定するには、下記の例のように cursor フィールドに batchSize を指定します。

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 フィールドを使用します。

照合を指定すると、大文字・小文字やアクセント記号など、文字列を比較するための言語独自のルールを指定できます。

コレクション myCollは、次のドキュメントを含みます。

{ _id: 1, category: "café", status: "A" }
{ _id: 2, category: "cafe", status: "a" }
{ _id: 3, category: "cafE", status: "a" }

下記の集計操作には 照合オプションが含まれます。

db.myColl.aggregate(
[ { $match: { status: "A" } }, { $group: { _id: "$category", count: { $sum: 1 } } } ],
{ collation: { locale: "fr", strength: 1 } }
);

照合フィールドの説明については、照合ドキュメントを参照してください。

次のドキュメントを使用してコレクション foodColl を作成します。

db.foodColl.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.foodColl.createIndex( { qty: 1, type: 1 } );
db.foodColl.createIndex( { qty: 1, category: 1 } );

下記の集計操作には、指定されたインデックスの使用を強制する hint オプションが含まれています。

db.foodColl.aggregate(
[ { $sort: { qty: 1 }}, { $match: { category: "cake", qty: 10 } }, { $sort: { type: -1 } } ],
{ hint: { qty: 1, category: 1 } }
)

デフォルトの読み取り保証 (read concern) レベルを上書きするには、readConcern オプションを使用します。getMore コマンドは、元の aggregate コマンドで指定された readConcern レベルを使用します。

$out または $merge ステージを、読み取り保証 "linearizable" と組み合わせて使用することはできません。つまり、"linearizable" 読み取り保証を db.collection.aggregate() に対して指定した場合は、どちらのステージもパイプライン内に含めることができません。

レプリカセットに対する次の操作では、大多数のノードに書き込まれたことが確認されたデータの最新のコピーを読み取るために、読み取り保証"majority" を指定します。

重要

  • $out ステージを含む集計に対して、読み取り保証レベル "majority" を指定できます。

  • 読み取り保証のレベルを問わず、ノード上の最新データにシステム内のデータの最新バージョンが反映されていない場合があります。

db.restaurants.aggregate(
[ { $match: { rating: { $lt: 5 } } } ],
{ readConcern: { level: "majority" } }
)

単一のスレッドでそれ自体の書き込みの読み取りを可能にするには、レプリカセットのプライマリに対して "majority" 読み取り保証と "majority" 書込み保証を使用します。

バージョン 5.0 で追加

コマンド内の他の場所からアクセスできる変数を定義するには、 letオプションを使用します。

注意

パイプライン $match ステージで変数を使用して結果をフィルター処理するには $expr 演算子内で変数にアクセスする必要があります。

さまざまなフレーバーのケーキの売上情報を含むコレクション 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 のケーキを検索します。

  • lettargetTotal 変数を定義します。これは $gt$$targetTotal として参照されます。

db.runCommand( {
aggregate: db.cakeSales.getName(),
pipeline: [
{ $match: {
$expr: { $gt: [ "$salesTotal", "$$targetTotal" ] }
} },
],
cursor: {},
let: { targetTotal: 3000 }
} )

Tip

以下も参照してください。

戻る

集計