janez89 / mongoose-materialized

mongoose materialized plugin
59 stars 22 forks source link

GetTree with childrens array? #6

Closed DJWassink closed 10 years ago

DJWassink commented 10 years ago

Hello, I was wondering if it is somehow possible to get a tree with a bit of a different structure. Currently when I call GetTree on a document I get something like this back:

{  
   "53ed04d4e0254ec41e4ad40e":{  
      "_id":"53ed04d4e0254ec41e4ad40e",
      "path":"",
      ........
      "children":{  
         "53ed04fbdff632fc1b5a4e1e":{  
            "_id":"53ed04fbdff632fc1b5a4e1e",
            "path":",53ed04d4e0254ec41e4ad40e",
            "parentId":"53ed04d4e0254ec41e4ad40e",
            ........
         },
         "53ed04e6dff632fc1b5a4e1b":{  ..........

(removed some key/values so it isn't to big) I was wondering if it was possible to get it returned like this:

[
    {
        "_id": "53ed04d4e0254ec41e4ad40e",
        "path": ,
        "children": [
              {
                  "_id": "53ed04fbdff632fc1b5a4e1e",
                  "path": ",53ed04d4e0254ec41e4ad40e",
                  "children": []
              }
         ]
     }
]

So basically all the documents are wrapped in a array so they are easy approachable, this way it is easier to navigate through a document its children when you return it as a tree. This notation is also the most supported notation for a lot of different modules/plugins. So it would be awesome if we can get this as a result so we can directly feed it to other modules.

janez89 commented 10 years ago

Hy, thank you for the feedback. Good idea, I'll try to do it this week.

janez89 commented 10 years ago

Hello, I had a little free time, so I made the requested function.

You can use npm tool for update and checkout the changelog and API reference. https://github.com/janez89/mongoose-materialized#changelog

DJWassink commented 10 years ago

Haha that was pretty damn quick! Awesome job man, Will check them out!

DJWassink commented 10 years ago

Just tested the functions, really impressed with the quality work! Something did surprise me though. If you use

Cat.GetArrayTree('elemt ID', function (err, tree) {
    // ...
});

It returns the tree correctly but if you let's say input a id of 10 and 10 has a few parents it will also include parents, is this working as intended? (the way I did it now was with a findById and then ask the tree which returned only the tree starting from that ID).

Anyhow I am so thankful for the (quick) fulfilment of this feature! I also made a function that is able to import a arrayTree and write it to the db, maybe it is not perfectly written but I will leave it here if people ever need a feature that's similar.

importDataArray: function(db, json, name, callback) {
    var self = this;
    var counter = 0;

    json.forEach(function(node) {
        counter++;
        self.importDataObj(db, node, name, function(err) {
            if (err) {
                callback(err);
            } else {
                counter--;
                if (counter === 0) {
                    callback();
                }                   
            }
        });
    });
},
importDataObj: function(db, node, name, callback) {
    var self = this;
    var counter = 1;
    var callbackCheck = false;

    if (name) {
        node.data.name = name;
    }

    saveNode(node, null);

    function saveNode(json, parentId) {
        counter--;

        if(json.children !== undefined) {
            counter += json.children.length;
        }

        var newNode = {};
        newNode = extend(true, newNode, json);

        newNode.parentId = parentId;
        delete newNode._id;
        delete newNode.path;
        delete newNode.children;

        self.saveNode(db, newNode, function(err, result) {
            if (err) {
                console.log(err);
                callback(err);
            } else {
                if (json.children !== undefined) {
                    for (var i = 0; i < json.children.length; i++) {
                        saveNode(json.children[i], result._id);
                    }
                }
            }
            if (counter === 0 && !callbackCheck) {
                callbackCheck = true;
                callback();
            }
        });
    }
}
andrzejs commented 9 years ago

Hi janez89 and Lailend, I try to limit result of query

Cat.GetArrayTree('elemt ID', function (err, tree) {
    // ...
});

and have array with only one level of children node

{
  "items": [
    {
      "id": "53a97576bcdd8dbc905727ac",
      "text": "Cars",
      "children": [
        {
          "id": "543c35b78521e35432b790c6",
          "text": "VW"
        },
        {
          "id": "53a9958cbcdd8dbc905727ad",
          "text": "Volvo"
        }
      ]
    }
  ]
}

and function to return this

            Category.model.findOne({_id: nodeID}, function(err, node){
                node.getArrayTree(function(err, childs) {           
                sendResponse({

                                items: childs.map(function(i){
                                        return {
                                            id: i.id
                                            ,text: i.name
                                            ,children: i.children.map(function(j){
                                                return {
                                                    id: j.id
                                                    ,text: j.name
                                                }
                                            })
                                        }

                                    })

                                })
                                                    })

How reduce resultset of function GetArrayTree to some fields and have all children levels? Plase help. Andrzej