Reputation: 657
I have a collection with documents similar to
{
"senderName" : "John",
"receiverName" : "Doe"
}
I am trying to perform an aggregation operation on the collection where I would like to have a set of names (which combines both senderName
and receiverName
so that I have something like
names:["John", "Doe"]
Is there a way to achieve this with Mongo aggregation framework. Also, I am unfortunately stuck with mongo 2.4 for solving this problem.
Upvotes: 2
Views: 2503
Reputation: 151112
In Modern releases of MongoDB the most efficient way is to simply notate the new field as an array. This was allowed from MongoDB 3.2:
db.collection.aggregate([
{ "$project": {
"names": [ "$senderName", "$receiverName" ]
}}
])
Probably the easiest way to do this us using the $map
operator introduced in MongoDB 2.6. It transforms arrays so that is what you basically do:
db.collection.aggregate([
{ "$project": {
"names": { "$map": {
"input": { "$literal": ["first","last"] },
"as": "el",
"in": { "$cond": [
{ "$eq": [ "$$el", "first" ] },
"$senderName",
"$receiverName"
]}
}}
}}
])
Alternately you can do a similar process with earlier versions that don't support the operator, but not really efficiently:
db.collection.aggregate([
{ "$project": {
"senderName": 1,
"receiverName": 1,
"type": { "$const": [ "first", "last" ] }
}},
{ "$unwind": "$type" },
{ "$group": {
"_id": "$_id",
"names": { "$push": { "$cond": [
{ "$eq": [ "$type", "first" ] },
"$senderName",
"$receiverName"
]}}
}}
])
But since in either case you are not really aggregating anything it is a fair argument to use a similar map
approach in client code by your languages own supported operation for this. But if you need to use it for some stage of your aggregation then you have to.
You can still do it though, and that is how.
Upvotes: 4