リレーショナルデータベースで標準的に提供される UNION ALL は、複数のクエリ出力を重複を含めて縦方向に連結する際の実用的な機能です。MongoDBにはこの構文が直接実装されていませんが、集計フレームワークのステージを組み上げることで同等の動作を正確に再現できます。
集計パイプラインによる結合アプローチ
異なるデータソースや同一コレクション内の別条件を単一のストリームに統合するには、MongoDB 5.0以降で導入された $unionWith ステージが最も効率的です。これにより、複数のコレクションに対して並列的な結合処理を宣言的に記述でき、追加の結合ロジックや変換ステージをパイプラインにシームレスに接続できます。
検証用データ環境の構築
動作確認のために accounts と transactions の2つのコレクションを準備し、代表的なドキュメントを投入します。
// accounts コレクションの初期化
db.createCollection("accounts")
db.accounts.insertMany([
{ accId: "ACC-101", holder: "Yamada", status: "active" },
{ accId: "ACC-102", holder: "Sato", status: "suspended" }
])
// transactions コレクションの初期化
db.createCollection("transactions")
db.transactions.insertMany([
{ txId: "TXN-501", accId: "ACC-101", amount: 25000, type: "credit" },
{ txId: "TXN-502", accId: "ACC-102", amount: 8000, type: "debit" }
])
UNION ALL 相当の集計処理
以下は、両コレクションのドキュメントを結合し、必要に応じてメタデータや型識別子を付加する集計パイプラインの実装例です。
db.accounts.aggregate([
{ $match: { status: "active" } },
{ $project: { accId: 1, holder: 1, recordOrigin: "accounts" } },
{
$unionWith: {
coll: "transactions",
pipeline: [
{ $match: { amount: { $gte: 5000 } } },
{ $project: { txId: 1, amount: 1, recordOrigin: "transactions" } }
]
}
},
{ $addFields: { processedAt: new Date() } }
])
パイプラインの処理順序を追うと、まずはベースコレクションに対して $match と $project を適用し、必要なフィールドを抽出します。続いて $unionWith で外部コレクションを参照し、その内部に定義されたサブパイプラインで独立したフィルタリングと投影を行います。この時点で両者の出力が同じスキーマ構造に整えられ、ドキュメントが連続したストリームとして流下します。最後の $addFields では結合後の全レコードに対して共通のタイムスタンプを付与し、結果セットを完結させます。