Reputation: 3450
I have two collections with following document structure : comment collection:
{
"_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")
}
users collection:
{
"_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"
}
I tried to join them and need them to follow the same document schema after join. I did
db.getCollection('users').aggregate([
{
$lookup: {
from: "comments",
localField: "unique_Id",
foreignField: "userId",
as: "goldStandard"
}
},
{ $out : "test2"}
])
output:
{
"_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")
}
]
}
Now, the "from" collections documents are added as objects under the "as" field name of type array. If I use $unwind to unwind the array, then it is given as an object. I do not want to be as an object, instead, I want the final documents to have the following structure after join: The field with the matching conditions in $lookup & common columns should be combined together to avoid duplicate fields. The new fields will be added to the new documents. For Example:
{
"_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")
}
Please suggest.
Upvotes: 1
Views: 1812
Reputation: 75984
You can use $mergeObject
operator which will be in upcoming 3.6 release.
$mergeObject
to merge the fields with the joined collection fields followed by $replaceRoot
to promote the combined doc to top level.
$project
with exclusion to drop the goldStandard
field and $out
to write to new collection.
Something like
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"
}
])
Upvotes: 3