node.js - Convert flat data into hierarchy in mongodb using Mongoose -


i have created model has following properties:

  1. id
  2. children
  3. parent

if parent set null document treated top level parent. each document may or may not have list of children contains id's of other document.

db.categories.insert( { _id: "mongodb", children: [],name: '', parent: 'databases'} ) db.categories.insert( { _id: "dbm", children: [], parent: 'databases' } ) db.categories.insert( { _id: "databases", children: [ "mongodb", "dbm" ], parent: 'programming' } ) db.categories.insert( { _id: "languages", children: [], parent: 'programming' } ) db.categories.insert( { _id: "programming", children: [ "databases", "languages" ],parent: 'books' } ) db.categories.insert( { _id: "books", children: [ "programming" ],parent: null } ) 

from above model, need generate output this:

{     name: "books",     nodes: [         {             name: "programming",             nodes: [                 {                     name: "databases",                     nodes: [                         {                             name: "monogodb"                         },                         {                             name: "dbm"                         }                     ]                 },                 {                     name: "languages"                 }             ]         }     ] } 

so far have tried this, because of async nature of findbyid(), not getting desired result.please suggest changes.

mydoc.find({     parent: null   }, function (err, topics) {     if (err) {       return handleerror(res, err);     }     var doctree = [];     _.each(document, function(parentdoc) {        var doc = {};        doc.text = parentdoc.name;       doc.nodes = [];       _.each(parentdoc.children, function(child) {         doc.nodes.push(processchildren(child));       });       doctree.push(doc);      });    function processchildren(child) {    mydoc.findbyid(child, function (err,item) {     var doc = {};     doc.name = item._doc.name;     doc.nodes = [];     if (item._doc.children === null) {       return topic;     } else {       _.each(item._doc.children, function (chld) {         processchildren(chld);       });     }     return doc;   });  }; 

you can try calling lean() method after find() method since documents returned queries lean option enabled plain javascript objects. can manipulate objects hierarchical structure want. following may not give exact desired result push right direction:

model.find({}).lean().exec(function (err, docs) {     if (err) {       return handleerror(res, err);     }     var i, len, temp, top_level, id, parent, hierarchical, nodependingobj, doc, _id, _parent, _children;     = 0;     top_level = [];     temp = {};     obj = {};     nodependingobj = {};     _id = '_id';     _parent = 'parent';     _children = 'children';      _.each(docs, function(doc) {         id = doc['_id'];         parent = doc[_parent];         temp[id] = doc;         if (parent === undefined || parent === null) {                   obj["name"] = id;             obj["nodes"] = doc[_children];             top_level.push(obj);         }          else {             if (temp[parent] !== undefined) {                            if (temp[parent][_children] === undefined) {                     temp[parent][_children] = [];                 }                 var o = {};                 o["name"] = id;                 if (doc[_children].length !== 0) o["nodes"] = doc[_children];                 temp[parent][_children].push(o);             } else {                             if (nodependingobj[parent] === undefined) {                     nodependingobj[parent] = [];                 }                 var o = {};                 o["name"] = id;                 if (doc[_children].length !== 0) o["nodes"] = doc[_children];                 nodependingobj[parent].push(o);                          }                 delete doc[_parent];         }          if (nodependingobj[id] !== undefined) {                   var len = nodependingobj[id].length;             if (doc[_children] === undefined) {                 doc[_children] = [];             }             while (len-- > 0) {                 doc[_children].push(nodependingobj[id].shift());             }         }     });      if (top_level.length === 1) {         hierarchical = top_level[0];     } else if (top_level.length > 1) {         hierarchical = {};         hierarchical[_children] = top_level;     } else {         hierarchical = {};     }     console.log(json.stringify(hierarchical)); }); 

check demo below.

var documents = [  	{  		"_id" : "mongodb",  		"children" : [],  		"name" : "",  		"parent" : "databases"  	},{  		"_id" : "dbm",  		"children" : [],  		"parent" : "databases"  	},{  		"_id" : "databases",  		"children" : [   			"mongodb",   			"dbm"  		],  		"parent" : "programming"  	},{  		"_id" : "languages",  		"children" : [],  		"parent" : "programming"  	},{  		"_id" : "programming",  		"children" : [   			"databases",   			"languages"  		],  		"parent" : "books"  	},{  		"_id" : "books",  		"children" : [   			"programming"  		],  		"parent" : null  	}  ];  var i, len, temp, top_level, id, parent, hierarchical, nodependingobj, doc, _id, _parent, _children;  = 0;  top_level = [];  temp = {};  obj = {};  nodependingobj = {};  _id = '_id';  _parent = 'parent';  _children = 'children';      _.each(documents, function(doc) {	  	id = doc['_id'];  	parent = doc[_parent];  	temp[id] = doc;  	if (parent === undefined || parent === null) {		  		obj["name"] = id;  		obj["nodes"] = doc[_children];  		top_level.push(obj);  	}   	else {  		if (temp[parent] !== undefined) {			  			if (temp[parent][_children] === undefined) {  				temp[parent][_children] = [];  			}  			var o = {};  			o["name"] = id;  			if (doc[_children].length !== 0) o["nodes"] = doc[_children];  			temp[parent][_children].push(o);  		} else {			  			if (nodependingobj[parent] === undefined) {  				nodependingobj[parent] = [];  			}  			var o = {};  			o["name"] = id;  			if (doc[_children].length !== 0) o["nodes"] = doc[_children];  			nodependingobj[parent].push(o);  			  		}      		delete doc[_parent];  	}  	  	if (nodependingobj[id] !== undefined) {		  		  		var len = nodependingobj[id].length;  		if (doc[_children] === undefined) {  			doc[_children] = [];  		}  		while (len-- > 0) {  			doc[_children].push(nodependingobj[id].shift());  		}  	}  });    if (top_level.length === 1) {  	hierarchical = top_level[0];  } else if (top_level.length > 1) {  	hierarchical = {};  	hierarchical[_children] = top_level;  } else {  	hierarchical = {};  }    pre.innerhtml = json.stringify(hierarchical, null, 4);
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.7.0/underscore-min.js"></script>  <pre id="pre"></pre>


Comments

Popular posts from this blog

toolbar - How to add link to user registration inside toobar in admin joomla 3 custom component -

linux - disk space limitation when creating war file -