如何合并集合以获取相同的文档架构?

时间:2017-09-14 18:07:28

标签: mongodb mongodb-query aggregation-framework

我有两个具有以下文档结构的集合: 评论集:

{ 
    "_id" : ObjectId("59bab6c6d41dce6422af08cd"), 
    "userId" : 12345.0, 
    "comment" : "Hey, what's up?", 
    "created" : ISODate("2017-09-14T17:05:10.820+0000")
}
{ 
    "_id" : ObjectId("59bab6c6d41dce6422af08ce"), 
    "userId" : 123456.0, 
    "comment" : "Not much", 
    "created" : ISODate("2017-09-14T17:05:10.855+0000")
}
{ 
    "_id" : ObjectId("59bab6c6d41dce6422af08cf"), 
    "userId" : 12345678.0, 
    "comment" : "Cool", 
    "created" : ISODate("2017-09-14T17:05:10.889+0000")
}
{ 
    "_id" : ObjectId("59bab6c6d41dce6422af08d0"), 
    "userId" : 12.0, 
    "comment" : "Nothing", 
    "created" : ISODate("2017-09-14T17:05:10.931+0000")
}

用户集合:

{ 
    "_id" : ObjectId("59bab74cd41dce6422af08d1"), 
    "unique_Id" : 12345.0, 
    "firstName" : "Rich", 
    "lastName" : "S", 
    "gender" : "M", 
    "country" : "CA", 
    "age" : "18"
}
{ 
    "_id" : ObjectId("59bab74cd41dce6422af08d2"), 
    "unique_Id" : 123456.0, 
    "firstName" : "Rob", 
    "lastName" : "M", 
    "gender" : "M", 
    "country" : "US", 
    "age" : "25"
}
{ 
    "_id" : ObjectId("59bab74cd41dce6422af08d3"), 
    "unique_Id" : 12345.0, 
    "firstName" : "Sarah", 
    "lastName" : "T", 
    "gender" : "F", 
    "country" : "US", 
    "age" : "13"
}

我尝试加入它们,并且需要它们在加入后遵循相同的文档架构。 我做了

db.getCollection('users').aggregate([
    {
        $lookup: {
            from: "comments",
            localField: "unique_Id",
            foreignField: "userId",
            as: "goldStandard"
        }

    },
    { $out : "test2"}
])

输出:

{ 
    "_id" : ObjectId("59bab74cd41dce6422af08d1"), 
    "unique_Id" : 12345.0, 
    "firstName" : "Rich", 
    "lastName" : "S", 
    "gender" : "M", 
    "country" : "CA", 
    "age" : "18", 
    "goldStandard" : [
        {
            "_id" : ObjectId("59bab6c6d41dce6422af08cd"), 
            "userId" : 12345.0, 
            "comment" : "Hey, what's up?", 
            "created" : ISODate("2017-09-14T17:05:10.820+0000")
        }
    ]
}
{ 
    "_id" : ObjectId("59bab74cd41dce6422af08d2"), 
    "unique_Id" : 123456.0, 
    "firstName" : "Rob", 
    "lastName" : "M", 
    "gender" : "M", 
    "country" : "US", 
    "age" : "25", 
    "goldStandard" : [
        {
            "_id" : ObjectId("59bab6c6d41dce6422af08ce"), 
            "userId" : 123456.0, 
            "comment" : "Not much", 
            "created" : ISODate("2017-09-14T17:05:10.855+0000")
        }
    ]
}
{ 
    "_id" : ObjectId("59bab74cd41dce6422af08d3"), 
    "unique_Id" : 12345.0, 
    "firstName" : "Sarah", 
    "lastName" : "T", 
    "gender" : "F", 
    "country" : "US", 
    "age" : "13", 
    "goldStandard" : [
        {
            "_id" : ObjectId("59bab6c6d41dce6422af08cd"), 
            "userId" : 12345.0, 
            "comment" : "Hey, what's up?", 
            "created" : ISODate("2017-09-14T17:05:10.820+0000")
        }
    ]
}

现在,“from”集合文档被添加为类型为array的“as”字段名下的对象。如果我使用$ unwind来展开数组,那么它将作为一个对象给出。我不想成为一个对象,相反,我希望最终文档在加入后具有以下结构: $ lookup&中具有匹配条件的字段应将公共列组合在一起以避免重复字段。新字段将添加到新文档中。例如:

{ 
    "_id" : ObjectId("59bab74cd41dce6422af08d1"), 
    "unique_Id" : 12345.0, 
    "firstName" : "Rich", 
    "lastName" : "S", 
    "gender" : "M", 
    "country" : "CA", 
    "age" : "18",  
    "comment" : "Hey, what's up?", 
    "created" : ISODate("2017-09-14T17:05:10.820+0000")
}
{ 
    "_id" : ObjectId("59bab74cd41dce6422af08d2"), 
    "unique_Id" : 123456.0, 
    "firstName" : "Rob", 
    "lastName" : "M", 
    "gender" : "M", 
    "country" : "US", 
    "age" : "25", 
    "comment" : "Not much", 
    "created" : ISODate("2017-09-14T17:05:10.855+0000")
}
{ 
    "_id" : ObjectId("59bab74cd41dce6422af08d3"), 
    "unique_Id" : 12345.0, 
    "firstName" : "Sarah", 
    "lastName" : "T", 
    "gender" : "F", 
    "country" : "US", 
    "age" : "13", 
    "comment" : "Hey, what's up?", 
    "created" : ISODate("2017-09-14T17:05:10.820+0000")
}

请建议。

1 个答案:

答案 0 :(得分:3)

您可以使用$mergeObject运算符,该运算符将在即将发布的3.6版本中使用。

$mergeObject将字段与已加入的集合字段合并,后跟$replaceRoot,以将合并后的文档提升到最高级别。

$project,请排除goldStandard字段,$out写入新收藏。

这样的东西
db.getCollection('users').aggregate([
  {
    "$lookup": {
      "from": "comments",
      "localField": "unique_Id",
      "foreignField": "userId",
      "as": "goldStandard"
    }
  },
  {
    "$replaceRoot": {
      "newRoot": {
        "$mergeObjects": [
          "$$ROOT",
          {
            "$arrayElemAt": [
              "$goldStandard",
              0
            ]
          }
        ]
      }
    }
  },
  {
    "$project": {
      "goldStandard": 0
    }
  },
  {
    "$out": "test2"
  }
])