MongoDBで「SQLUNION」方式でユニオンを実行するには、単一のクエリでルックアップとともに集計を使用できます。
このようなもの:
db.getCollection("AnyCollectionThatContainsAtLeastOneDocument").aggregate(
[
{ $limit: 1 }, // Reduce the result set to a single document.
{ $project: { _id: 1 } }, // Strip all fields except the Id.
{ $project: { _id: 0 } }, // Strip the id. The document is now empty.
// Lookup all collections to union together.
{ $lookup: { from: 'collectionToUnion1', pipeline: [...], as: 'Collection1' } },
{ $lookup: { from: 'collectionToUnion2', pipeline: [...], as: 'Collection2' } },
{ $lookup: { from: 'collectionToUnion3', pipeline: [...], as: 'Collection3' } },
// Merge the collections together.
{
$project:
{
Union: { $concatArrays: ["$Collection1", "$Collection2", "$Collection3"] }
}
},
{ $unwind: "$Union" }, // Unwind the union collection into a result set.
{ $replaceRoot: { newRoot: "$Union" } } // Replace the root to cleanup the resulting documents.
]);
仕組みの説明は次のとおりです。
-
aggregate
をインスタンス化します 任意から 少なくとも1つのドキュメントが含まれているデータベースのコレクション。データベースのコレクションが空にならないことを保証できない場合は、データベースに、ユニオンクエリを実行するために特別に存在する単一の空のドキュメントを含むある種の「ダミー」コレクションを作成することで、この問題を回避できます。 -
パイプラインの最初のステージを
{ $limit: 1 }
にします 。これにより、最初のドキュメントを除くコレクションのすべてのドキュメントが削除されます。 -
$project
を使用して、残りのドキュメントのすべてのフィールドを削除します ステージ:{ $project: { _id: 1 } }, { $project: { _id: 0 } }
-
これで、集計に単一の空のドキュメントが含まれます。結合するコレクションごとにルックアップを追加します。
pipeline
を使用できます 特定のフィルタリングを実行するフィールド、またはlocalField
を残すフィールド およびforeignField
コレクション全体に一致するようにnullとして。{ $lookup: { from: 'collectionToUnion1', pipeline: [...], as: 'Collection1' } }, { $lookup: { from: 'collectionToUnion2', pipeline: [...], as: 'Collection2' } }, { $lookup: { from: 'collectionToUnion3', pipeline: [...], as: 'Collection3' } }
-
これで、次のような3つの配列を含む単一のドキュメントを含む集計が作成されました。
{ Collection1: [...], Collection2: [...], Collection3: [...] }
次に、
$project
を使用して、それらを1つの配列にマージできます。$concatArrays
と一緒にステージング 集計演算子:{ "$project" : { "Union" : { $concatArrays: ["$Collection1", "$Collection2", "$Collection3"] } } }
-
これで、単一のドキュメントを含む集計が作成され、その中にコレクションの結合を含む配列が配置されます。まだやるべきことは、
$unwind
を追加することです。 および$replaceRoot
配列を個別のドキュメントに分割する段階:{ $unwind: "$Union" }, { $replaceRoot: { newRoot: "$Union" } }
-
Voilà。結合したいコレクションを含む結果セットがあることを知っています。次に、ステージを追加してさらにフィルタリングし、並べ替え、skip()とlimit()を適用できます。ほぼすべてのもの。