Home > database >  MongoDB Aggregation - Flatten resultat
MongoDB Aggregation - Flatten resultat

Time:07-22

db.collection.aggregate([
              ....
    { $group: {_id: "$data.r.id", "col": {$first: "$data.r"}}},
    {$project:{"o":{"$objectToArray":"$col"}}},
    {$unwind:"$o"},
    {$group:{"_id":null, "keys":{$addToSet:"$o.k"}}},
    {$project: {"keys":1, "_id": 0}},
    {$addFields: {res:{$map:{ input:"$keys", as: "a", in: {"_id":0,"label": "$$a"}}}}},
    {$project: {"res":1}}
])

With my MongoDB query, the output is:

{ 
  "res" : [
     {
         "_id" : 0.0, 
         "label" : "aaaa"
     }, 
     {
         "_id" : 0.0, 
         "label" : "bbbbb"
     }, 
     {
         "_id" : 0.0, 
         "label" : "ccccc"
     }
  ] 
}

and I try to output this:

{
    "_id" : 0.0, 
    "label" : "aaaa"
}, 
{
    "_id" : 0.0, 
    "label" : "bbbb"
}, 
{
    "_id" : 0.0, 
    "label" : "cccc"
}

so I added:

{$replaceRoot : {"newRoot": "$res"}}

but I got this error:

''newRoot' expression must evaluate to an object, but resulting value was: [{_id: 0, label: "aaaa"},{_id: 0, label: "bbbb"},{_id: 0, label: "cccc"}]

How can I remove the nested object "res" to return only the list/array of objects (id, label)?

CodePudding user response:

Re-write the answer from the comment to resolve the question.

You need to flatten the deconstruct res array first

{ $unwind: "$res" }

before replacing the input documents with

{
  $replaceRoot: {
    newRoot: "$res"
  }
}

CodePudding user response:

The answer was:

db.collection.aggregate([
              ....
    { $group: {_id: "$data.r.id", "col": {$first: "$data.r"}}},
    {$project:{"o":{"$objectToArray":"$col"}}},
    {$unwind:"$o"},
    {$group:{"_id":null, "keys":{$addToSet:"$o.k"}}},
    {$project: {"keys":1, "_id": 0}},
    {$addFields: {res:{$map:{ input:"$keys", as: "a", in: {"_id":0,"label": "$$a"}}}}},
    {$project: {"res":1}},
    {$unwind:"$res"},
    {$replaceRoot: {"newRoot": "$res"}}
])

thanks a lot

  • Related