Stephen
Stephen

Reputation: 3465

Project array of Objects to Key Value

After aggregations i get this result,

{
    "_id" : {
        "date" : ISODate("2017-08-30T00:00:00.000Z")
    },
    "aggr" : [ 
        {
            "gender" : "unknown",
            "count" : 365
        }, 
        {
            "gender" : "male",
            "count" : 2
        }
    ]
}

Is it possible to convert this into below format

{
    "date" : ISODate("2017-08-30T00:00:00.000Z"),
    "unknown" : 365,
    "male" : 2
}

Tried using $unwind and $project, but couldn't convert array objects into key,value pairs

Upvotes: 0

Views: 1001

Answers (1)

Neil Lunn
Neil Lunn

Reputation: 151190

Yes, using $arrayToObject and $map to convert the existing array to a format it accepts:

db.collection.aggregate([
  { "$replaceRoot": {
    "newRoot": {
      "$arrayToObject": {
        "$concatArrays": [
          [{ "k": "date", "v": "$_id.date" }],  
          { "$map": {
            "input": "$aggr",
            "in": { "k": "$$this.gender", "v": "$$this.count" }
          }}
        ]
      }
    }    
  }}
])

Of course if this is actually only on the "tail" of an existing aggregation and you don't have at least MongoDB 3.4.4 where the operator is introduced, then you can simply reshape the result in the client code:

db.collection.aggregate([
  // existing pipeline
]).map(d => 
  Object.assign(
    { date: d._id.date },
    d.aggr.reduce((acc,curr) =>
      Object.assign(acc,{ [curr.gender]: curr.count }),{}
    )
  )
)

Upvotes: 1

Related Questions