Alexis Pavlidis
Alexis Pavlidis

Reputation: 11

Convert mongoose document to flat object

I want to retrieve a document from mongodb and then convert it a flat object or flat array.So lets say i am having this document:

{
    "_id":"57db3e2269d84bfc06ccecef",
    "profileId": {
        "_id":"57d838072902f1280324cc8d",
        "fname":"name",
        "lname":"name2"
    },
    "subjectId": {
        "_id":"57a0d71fb62eaf002e1258c2",
        "title":"Some Title
    },
    "comments": [{
        "_id":"57db3f046a8dde181a4cce65",
        "text":"fggg"
    }],
    "type":"post",
    "text":"dddddddddddddddddddddd",
    "datetime":"2016-09-16T00:34:42.888Z"
}

And I want to convert it like this(lets say i don`t need the ids of profileId and subjectId anymore):

{
    "_id":"57db3e2269d84bfc06ccecef",
    "fname":"name",
    "lname":"name2",
    "title":"Some Title,
    "comments":[
        "text":"fggg"
    ],
    "type":"post",
    "text":"dddddddddddddddddddddd",
    "datetime":"2016-09-16T00:34:42.888Z"
}

Upvotes: 1

Views: 1344

Answers (3)

Omar Vazquez
Omar Vazquez

Reputation: 407

I think that could be done with something like:

let myObj = {};
for(var key in myDocument) {
   switch(typeof myDocument[key]) {
      case 'object':
            if(!Array.isArray(myDocument[key])){
                  myObj[key] = {};
                  for(var objKey in myDocument[key]) {
                    if(objKey !== "_id") {
                     myObj[key][objKey] = myDocument[key][objKey];
                    }
                  }
                  break;
            } else {
                  let arr = [];
                  myDocument[key].forEach(function(el) {
                    if(typeof el == 'object') {
                      for(var elKey in el) {
                        if(elKey !== '_id') {
                          arr.push(el);
                        }
                      }
                    }
                  });
                  myObj[key] = arr;
                  break;
                }
      default: 
                  myObj[key] = myDocument[key];
  }
}

I've tried it and gives me this:

myObj = { _id: '57db3e2269d84bfc06ccecef',
  profileId: { fname: 'name', lname: 'name2' },
  subjectId: { title: 'Some Title' },
  comments: [ { _id: '57db3f046a8dde181a4cce65', text: 'fggg' } ],
  type: 'post',
  text: 'dddddddddddddddddddddd',
  datetime: '2016-09-16T00:34:42.888Z' }

But this answer could be optimized maybe because this is for a very exact approach

Upvotes: 0

DanielKhan
DanielKhan

Reputation: 1208

There are many viable solutions. Some are more dynamic some quite hardcoded. It depends on the complexity of the problem what is better in the end. As you don't want to include all elements, the simplest way to achieve that is to build this object on your own.

// mngObject is coming from mongoose.

mngObject.fname = mngObject.profileId.fname
// and so on

// At the end
delete mngObject.profileId;

Upvotes: 0

Derek Soike
Derek Soike

Reputation: 11650

Take a look at MongoDB's Aggregation Framework.

Something like this might do the trick:

db.<collection>.aggregate([

  // reformat all except comments
  {$project: {
    _id: '$_id', 
    fname: '$profileId.fname', 
    lname: '$profileId.lname', 
    title: '$subjectId.title', 
    comments: '$comments', 
    type: '$type', 
    text: '$text', 
    datetime: '$datetime'
  }},

  // unwind comments
  {$unwind: '$comments'},

  // re-formate with comments
  {$group: {
    _id: '$_id',
    fname: {$first: '$fname'},
    ...
    comments: {$push: '$comments.text'}
  }}
])

It's possible to accomplish the same thing with just the $unwind and $group stages, but I added the $project stage to demonstrate what it can do.


Or just write a script:

db.<collection>.find(function(err, docs) {

  if (err) {
    // handle error
  }

  // reformat docs
  var reshapedDocs = [];
  docs.forEach(function(doc) {
    var reshapedDoc = {};
    reshapedDoc.fname = doc.profileId.fname;
    // ...
    reshapedDoc.comments = [];
    doc.comments.forEach(function(comment) {
      reshapedDoc.comments.push(comment.text);
    });
    // ...
    reshapedDocs.push(reshapedDoc);
  });

});

Upvotes: 1

Related Questions