0

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

0

1 Answer 1

1

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 }),{}
    )
  )
)
Sign up to request clarification or add additional context in comments.

4 Comments

@Steve That's what the answer says, and it also says what to do in lower versions at the end of the pipeline instead. You cannot use a value as a keyname directly out of an aggregation pipeline in any lower version.
I am not writing the aggregation result to any collection, so prior to 3.4.4 is it not possible to do it in the aggregation itself?
@Steve How many different ways can I say No? I've already been pretty crystal clear on this point. That's why there is a new operator. If is were possible with something else then it would not have been introduced. And again if it's the "result" then simply modify in client code just like is being demonstrated.
@Steve Actually you seem confused. The example with .map() on the end simulates interacting with the cursor result of aggregation. Changed how I typed that in to make it more obvious\

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.