是否可以使用类似于 SQL 查询的 2 个或更多集合在 Mongo DB 中编写联合查询?
我正在使用 spring mongo 模板,在我的用例中,我需要根据某些条件从 3-4 个集合中获取数据。我们可以通过一次操作实现这一目标吗?
例如,我有一个名为“CircuitId”的字段,该字段存在于所有 4 个集合中。我需要从所有 4 个集合中获取该字段与给定值匹配的所有记录。
在 MongoDB 中以“SQL UNION”方式进行联合可以在单个查询中使用聚合和查找。
像这样的东西:
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
out of any数据库的集合,其中至少包含一个文档。如果您不能保证数据库的任何集合不为空,您可以通过在数据库中创建某种“虚拟”集合来解决此问题,其中包含一个专门用于执行联合查询的空文档。
使管道的第一阶段成为{ $limit: 1 }
。这将删除集合中除第一个文档之外的所有文档。
-
使用删除剩余文档的所有字段$project
stages:
{ $project: { _id: 1 } },
{ $project: { _id: 0 } }
-
您的聚合现在包含一个空文档。现在是为要合并在一起的每个集合添加查找的时候了。您可以使用pipeline
字段进行一些特定的过滤,或者离开localField
and 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
舞台与$concatArrays
聚合运算符:
{
"$project" :
{
"Union" : { $concatArrays: ["$Collection1", "$Collection2", "$Collection3"] }
}
}
-
您现在拥有一个包含单个文档的聚合,其中包含一个包含集合并集的数组。剩下要做的就是添加一个$unwind
and a $replaceRoot
将数组拆分为单独的文档的阶段:
{ $unwind: "$Union" },
{ $replaceRoot: { newRoot: "$Union" } }
瞧。您知道有一个结果集,其中包含您想要合并在一起的集合。然后,您可以添加更多阶段来进一步过滤、排序、应用skip() 和limit()。几乎任何你想要的东西。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)