合并两个集合中的数据

时间:2018-09-07 16:02:56

标签: mongodb mongoose aggregation-framework

如果我有一些数据存储在MongoDB的两个集合中,就像这样:

收藏1:

opened = [{id: 1, value: 1123}, {id: 2, value: 4231}, {id: 2, value: 3322}...]

收藏2:

synched = [{id: 1, value: 12343}, {id: 2, value: 12322}, {id: 1, value: 12322}...]

现在,我知道我可以对数据库进行两次调用并从这两个数据库获取数据,但是我对潜在地聚集调用并从两个集合中合并数据感兴趣,因此我最终得到以下结果:

result = {synched: [{id: 1, value: 12343},{id: 1, value: 12322}], opened: [{id: 1, value: 1123}]}

因此,就我而言,目前我只进行两次标准查询:

db.opened.find({id: 1}, function(err, res){})
db.synched.find({id: 1}, function(err, res){})

有没有办法将它们结合起来?

编辑:

我发布的原始问题有所发展。这是我需要处理的一点更改,以下答案不支持。

如果我有一个匹配的ID数组怎么办:

{ $match: { 'id': {$in: [1,2]} }}

因此,现在,limit呼叫确实把事情搞砸了。我需要的是synched的所有文档和opened的所有文档,它们与数组中的任何ID匹配,但是进行限制只能返回最先遇到的问题。并非总是如此。可能有多个具有相同id属性的文档。该属性不是唯一的_id

任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:1)

您可以尝试在mongodb 3.4中的以下聚合以及更高版本中

db.synched.aggregate([
  { "$limit": 1 },
  { "$facet": { 
    "synched": [
      { "$match": { "id": 1  }}
    ],
    "opened": [
      { "$match": { "id": 1  }},
      { "$limit": 1 },
      { "$lookup": {
        "from": "opened",
        "localField": "id",
        "foreignField": "id",
        "as": "opened"
      }},
      { "$unwind": "$opened" },
      { "$replaceRoot": { "newRoot": "$opened" }}
    ]
  }},
  { "$project": { "opened": 1, "synched": 1 }}
])

并使用新的$lookup语法

db.synched.aggregate([
  { "$facet": { 
    "synched": [
      { "$match": { "id"': { "$in": [1,2] }}}
    ],
    "opened": [
      { "$limit": 1 },
      { "$lookup": {
        "from": "opened",
        "pipeline": [
          { "$match": { "id"': { "$in": [1,2] }}}
        ],
        "as": "opened"
      }},
      { "$unwind": "$opened" },
      { "$replaceRoot": { "newRoot": "$opened" }}
    ]
  }},
  { "$project": { "opened": 1, "synched": 1 }}
])

答案 1 :(得分:0)

在这里,我有两个集合 Users User Profile

下面的方法将匹配请求的字段,还将两个集合合并并抛出所需的输出:

const getUserData = async (userId) => {
        const getUserDataByUserId = await userDataModel.aggregate([
            {
                $match: {
                    userId: userId
                }
            }, {
                $lookup: {
                    from: 'user_profiles',
                    localField: 'userId',
                    foreignField: 'userId',
                    as: 'users'
                }
            }, {
                $replaceRoot: {
                    newRoot: {
                        $mergeObjects: [{
                            $arrayElemAt: ["$users", 0]
                        }, "$$ROOT"]
                    }
                }
            }, {
                $project: {
                    fromItems: 0
                }
            }
        ]);

        return getUserDataByUserId;
    }