在MongoDB中以“SQL联合”的方式进行联合是可能的,可以在单个查询中使用聚合和查找。
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
从…里面
任何
数据库的集合,其中至少有一个文档。如果不能保证数据库的任何集合都不会为空,可以通过在数据库中创建某种“虚拟”集合来解决此问题,该集合中包含一个空文档,专门用于执行联合查询。
-
{ $limit: 1 }
. 这将删除收藏中除第一个文件外的所有文件。
-
使用删除剩余文档的所有字段
$project
{ $project: { _id: 1 } },
{ $project: { _id: 0 } }
-
您的聚合现在包含单个空文档。是时候为每个要合并在一起的集合添加查找了。您可以使用
pipeline
字段来做一些特定的过滤,或者离开
localField
和
foreignField
{ $lookup: { from: 'collectionToUnion1', pipeline: [...], as: 'Collection1' } },
{ $lookup: { from: 'collectionToUnion2', pipeline: [...], as: 'Collection2' } },
{ $lookup: { from: 'collectionToUnion3', pipeline: [...], as: 'Collection3' } }
-
现在,您有了一个包含单个文档的聚合,该文档包含以下3个数组:
{
Collection1: [...],
Collection2: [...],
Collection3: [...]
}
$项目
舞台与
$concatArrays
聚合运算符:
{
"$project" :
{
"Union" : { $concatArrays: ["$Collection1", "$Collection2", "$Collection3"] }
}
}
-
$unwind
和a
$replaceRoot
将阵列拆分为单独文档的阶段:
{ $unwind: "$Union" },
{ $replaceRoot: { newRoot: "$Union" } }
-