MongoDB中的联合模拟

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":

在关系数据库中有UNION命令,例如在Microsoft SQL中。
对于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中没有更好的联合替代方案,您所能做的就是在两次往返中获取两个集合,并将结果合并到内存中。