MongoDB中的UNION模拟

时间:2018-02-19 18:07:37

标签: mongodb aggregation-framework union

关系数据库中有UNION命令,例如在Microsoft SQL中 对于Microsoft SQL,UNION声明

  

将两个或多个查询的结果合并到一个结果集中   包括属于union中所有查询的所有行。   UNION操作与使用组合列的连接不同   来自两张桌子。

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

结果" row-set"我希望按照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" }

P.S。:我已经阅读了以下问题,但是没有发现它有用 MongoDB: Combine data from multiple collections into one..how?
Merging two collections in MongoDB
MongoDB and “joins” [duplicate]

2 个答案:

答案 0 :(得分:1)

有一个$setUnion运算符可用,但你必须为它准备数据,但我认为有可能:

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$replaceRoot只是为了获取您希望的文档列表。)

答案 1 :(得分:1)

自MongoDB 4.4起,现在有了$unionWith聚合管道命令,使您可以简单地进行以下操作:

db.accounts.aggregate([
   { $unionWith: { coll: "packages" } }
])