Skynet
Skynet

Reputation: 657

Create an Array From two Fields

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

Answers (1)

Neil Lunn
Neil Lunn

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

Related Questions