MongoDB中的联合模拟
在关系数据库中有UNION命令,例如在Microsoft SQL中。MongoDB中的联合模拟,mongodb,aggregation-framework,union,Mongodb,Aggregation Framework,Union,在关系数据库中有UNION命令,例如在Microsoft SQL中。 对于Microsoft SQL,美国 将两个或多个查询的结果合并到单个结果集中 它包括属于联合中所有查询的所有行。 联合操作不同于使用合并列的联接 两张桌子 MongoDB中有类似于UNION的东西吗 我想解决的任务是合并来自两个集合的文档—帐户和包 客户 { "_id": 1, "accountId": 1, "accOld": "oldValue1", "accNew": "newValue1" }, { "_id":
对于Microsoft SQL,美国 将两个或多个查询的结果合并到单个结果集中 它包括属于联合中所有查询的所有行。 联合操作不同于使用合并列的联接 两张桌子 MongoDB中有类似于UNION的东西吗 我想解决的任务是合并来自两个集合的文档—帐户和包 客户
{ "_id": 1, "accountId": 1, "accOld": "oldValue1", "accNew": "newValue1" },
{ "_id": 2, "accountId": 1, "accOld": "oldValue2", "accNew": "newValue2" },
{ "_id": 3, "accountId": 2, "accOld": "oldValue1", "accNew": "newValue1" }
{ "_id": 1, "accountId": 1, "pckgOld": "packageOldValue1", "pckgNew": "packageNewValue1" },
{ "_id": 2, "accountId": 1, "pckgOld": "packageOldValue2", "pckgOld": "packageNewValue2" },
{ "_id": 3, "accountId": 2, "pckgOld": "packageOldValue3", "pckgOld": "packageNewValue4" },
{ "_id": 4, "accountId": 3, "pckgOld": "packageOldValue4", "pckgOld": "packageNewValue4" }
套餐
{ "_id": 1, "accountId": 1, "accOld": "oldValue1", "accNew": "newValue1" },
{ "_id": 2, "accountId": 1, "accOld": "oldValue2", "accNew": "newValue2" },
{ "_id": 3, "accountId": 2, "accOld": "oldValue1", "accNew": "newValue1" }
{ "_id": 1, "accountId": 1, "pckgOld": "packageOldValue1", "pckgNew": "packageNewValue1" },
{ "_id": 2, "accountId": 1, "pckgOld": "packageOldValue2", "pckgOld": "packageNewValue2" },
{ "_id": 3, "accountId": 2, "pckgOld": "packageOldValue3", "pckgOld": "packageNewValue4" },
{ "_id": 4, "accountId": 3, "pckgOld": "packageOldValue4", "pckgOld": "packageNewValue4" }
作为“行集”的结果,我想让下面的一个按accountId
字段逻辑分组进行排序
{ "accountId": 1, "accOld": "oldValue1", "accNew": "newValue1" },
{ "accountId": 1, "accOld": "oldValue2", "accNew": "newValue2" },
{ "accountId": 1, "pckgOld": "packageOldValue1", "pckgNew": "packageNewValue1" },
{ "accountId": 1, "pckgOld": "packageOldValue2", "pckgOld": "packageNewValue2" },
{ "accountId": 2, "accOld": "oldValue1", "accNew": "newValue1" }
{ "accountId": 2, "pckgOld": "packageOldValue3", "pckgOld": "packageNewValue4" },
{ "accountId": 3, "pckgOld": "packageOldValue4", "pckgOld": "packageNewValue4" }
附言:我已经阅读了以下问题,但没有发现有什么帮助有一个操作员可用,但您必须为其准备数据,但我认为这是可能的:
db.Accounts.aggregate([
{
$lookup: {
from: "Packages",
pipeline: [],
as: "packages"
}
},
{
$addFields: {
packages: {
$map: {
input: "$packages",
as: "package",
in: {
"accountId": "$$package.accountId",
"pckgOld": "$$package.pckgOld",
"pckgNew": "$$package.pckgNew",
}
}
}
}
},
{
$group: {
_id: null,
accounts: {
$push: {
accountId: "$accountId",
accOld: "$accOld",
accNew: "$accNew"
}
},
packages: {
$first: "$packages"
}
}
},
{
$project: {
items: {
$setUnion: ["$accounts", "$packages"]
}
}
},
{
$unwind: "$items"
},
{
$replaceRoot: {
newRoot: "$items"
}
}
])
基本上,
$lookup
用于合并两个集合。我们没有指定匹配字段,这意味着每个帐户都将所有产品作为嵌入式阵列。然后可以使用$map
删除不必要的属性。接下来,在$group
之后,我们在一个文档中嵌入了两个所需格式的数组。此时,我们可以使用$setUnion
合并两个数组。最后两个步骤($unwind
和仅用于获取所需的文档列表)。自从MongoDB 4.4以来,现在有了$unionWith
聚合管道命令,允许您简单地执行以下操作:
db.accounts.aggregate([
{ $unionWith: { coll: "packages" } }
])
嗨,米奇。非常感谢你的帮助。您是否有机会检查您的查询?我试过了,但它的一部分也出人意料地起作用。我只留下了
lookup
和addFields
部分,此查询只输出长度为零的包的帐户列表
字段。@LeshaPipiev,是的,我对您的示例数据执行了该查询,它返回的正是您期望的结果。你能检查一下你的MongoDB版本吗?我想你需要3.6分。第二件事:你的收藏品的名字是“包裹”吗?嗨,米奇。再次感谢你的帮助。您不认为这种方法在扩展方面很差吗。想象一下,会有5000个账户和30000个包裹。@Leshapipeev我同意。我在这里展示的只是一个概念证明,它适用于小集合,但如果您想要合并大集合,则肯定是一种过火的行为。目前我们在MongoDB中没有更好的联合替代方案,您所能做的就是在两次往返中获取两个集合,并将结果合并到内存中。