将mongoose文档转换为扁平对象

时间:2016-10-13 22:37:05

标签: node.js mongodb

我想从mongodb中检索文档,然后将其转换为平面对象或平面数组。所以我想说我有这个文档:

{
    "_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"
}

我想像这样转换它(假设我不再需要profileId和subjectId的ID):

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

3 个答案:

答案 0 :(得分:0)

有许多可行的解决方案。有些是更有活力的,有些硬编码。 这取决于问题的复杂性到底有什么好处。 由于您不想包含所有元素,因此最简单的方法是自己构建此对象。

// mngObject is coming from mongoose.

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

// At the end
delete mngObject.profileId;

答案 1 :(得分:0)

看看MongoDB的Aggregation Framework

这样的事情可能会起到作用:

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'}
  }}
])

只有$unwind$group阶段才能完成同样的事情,但我添加了$project阶段来演示它可以做什么。

或者只是写一个脚本:

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);
  });

});

答案 2 :(得分:0)

我认为可以通过以下方式完成:

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];
  }
}

我已经尝试过并给了我这个:

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' }

但是这个答案可能会被优化,因为这是一个非常精确的方法