Jitesh Tukadiya
Jitesh Tukadiya

Reputation: 1339

Unwind object in mongodb

I have a collection like this

[{
    "_id" : ObjectId("590c2331dc1a05e7d3525e70"),
    "name" : "Orange",
    "quarters" : {
        "first" : 20,
        "middle" : 53,
        "last" : 52
    }
}, {
    "_id" : ObjectId("590c2405dc1a05e7d3525e71"),
    "name" : "Apple",
    "quarters" : {
        "first" : 42,
        "middle" : 37,
        "last" : 16
    }
}]

and I want result like this

[{
    name: "Orange",
    first: 20
},{
    name: "Orange",
    middle: 53
},{
    name: "Orange",
    last: 52
},{
    name: "Apple",
    first: 42
},{
    name: "Apple",
    middle: 37
},{
    name: "Apple",
    last: 16
}]

I tried to find the solution and I found few question similar to this question but no luck

Thanks in advance

Upvotes: 1

Views: 5577

Answers (2)

s7vr
s7vr

Reputation: 75914

You can try below aggregation pipeline in 3.4.4 version.

Change the quarters embedded document into array of key value pairs using $objectToArray followed by $unwind and $zip each quarters key value pair separately followed by $arrayToObject to create original structure.

Use $addFields to push the name field into quarters.

Use $replaceRoot to promote the quarters embedded document to top level.

db.collection.aggregate([
{$addFields: {quarters: {$objectToArray: "$quarters"}}}, 
{$unwind:"$quarters"},
{$addFields:{quarters: {"$arrayToObject":{$zip:{inputs:[["$quarters.k"], ["$quarters.v"]]}}}}},
{$addFields:{"quarters.name": "$name"}},
{$replaceRoot:{newRoot:"$quarters"}}
])

Upvotes: 9

Arpit Kumar
Arpit Kumar

Reputation: 2249

You can get it like this:

var inputCollection = [{
    "_id" : ObjectId("590c2331dc1a05e7d3525e70"),
    "name" : "Orange",
    "quarters" : {
        "first" : 20,
        "middle" : 53,
        "last" : 52
    }
}, {
    "_id" : ObjectId("590c2405dc1a05e7d3525e71"),
    "name" : "Apple",
    "quarters" : {
        "first" : 42,
        "middle" : 37,
        "last" : 16
    }
}];

var output = [];

inputCollection.forEach(function(obj){
    for (var key in obj.quarters) {
      if (obj.quarters.hasOwnProperty(key)) {
         output.push({ name:obj.name, key: obj.quarters[key] });
      }
    }
});

console.log("The output is :", output); // It will print your desired output.

I hope this will help.

Thanks.

Upvotes: 1

Related Questions