Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to combine two objects in mongodb aggregation project stage?

I had the following array of structure in my aggregation pipeline. Tried merge objects and setUnion operators.

{ 
  combs:[
    [
      {
        name:"A",
        c_type:"A"
      },
      {
        type:"visual",
        severity:"Normal"
      }
    ],
    [
      {
        name:"B",
        c_type:"B"
      },
      {
        type:"visual",
        severity:"Normal"
      }
    ]
  ]
}

I am expecting the following results to produce some statistics. Please help me.

{ 
  combs:[
    {
      name:"A",
      c_type:"A",
      type:"visual",
      severity:"Normal"
    }
    {
      name:"B",
      c_type:"B",
      type:"visual",
      severity:"Normal"
     }
  ]
}
like image 608
Krishna Dev Avatar asked Sep 23 '19 05:09

Krishna Dev


1 Answers

"Is it possible to achieve without $unwind operation?"

Well YES. As long as your structure of arrays of arrays is consistently mapped that way then you really only need a single stage in the pipeline:

db.collection.aggregate([
  { "$addFields": {
     "combs": {
       "$map": {
         "input": "$combs",
         "in": { "$mergeObjects": "$$this" }
       }
     }
  }}
])

So really the $map operator takes place here as a much more efficient method than $unwind for processing each array element. Also since $mergeObjects is expecting "an array of objects", this is what each element of your array of arrays actually is. So simply { "$mergeObjects": "$$this" } on each outer member of the array.

Produces the output from your supplied data:

{
        "_id" : ObjectId("5d8865c273375a6a4cc9e76a"),
        "combs" : [
                {
                        "name" : "A",
                        "c_type" : "A",
                        "type" : "visual",
                        "severity" : "Normal"
                },
                {
                        "name" : "B",
                        "c_type" : "B",
                        "type" : "visual",
                        "severity" : "Normal"
                }
        ]
}

Generally you should always prefer an inline processor like $map or other array operators in preference to $unwind where applicable.

like image 70
Neil Lunn Avatar answered Sep 29 '22 08:09

Neil Lunn