SitePoint Sponsor

User Tag List

Page 4 of 6 FirstFirst 123456 LastLast
Results 76 to 100 of 141
  1. #76
    SitePoint Enthusiast
    Join Date
    Sep 2005
    Location
    Edinburgh, UK
    Posts
    51
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Great article helps me a lot :)

  2. #77
    Oth
    SitePoint Community Guest
    Where are the functions for adding/deleting nodes for the modified preorder tree traversal ?

  3. #78
    SitePoint Zealot ShytKicka's Avatar
    Join Date
    Aug 2004
    Location
    New York
    Posts
    120
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Good Article.

  4. #79
    Tester
    SitePoint Community Guest
    Great article.

    Tip for anyone who wants to make a website menu using the Tree Traversal:

    You'll get an error in your php syntax when you want to display the data on screen. This is because the while statement shown assumes there is always a top item (see page 2 of article).

    Simply add "count($right) > 0 &&" (no quotes) to the while statement, so it becomes:
    <?php
    while( count($right) > 0 && $right[count($right)-1] < $row['rgt'] ){
    array_pop($right);
    ?>

  5. #80
    SitePoint Enthusiast
    Join Date
    Apr 2006
    Posts
    29
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Great article.

    But i have a problem with your way :

    1- your script get all childrens for a specific parents. no level limitation.

    What if i want get a childrens for a specific level dep? eg:

    In your Script if i want to get "Fruit" childrens i will get some thing like this :

    -Fruit
    ---Red
    -----Cherry
    -----Strawberry
    -----Yellow
    -------Banana
    ----------Meat
    ----------Beef
    ----------Pork

    but what if i want to get "Fruit" childrens BUT for 2 level .
    eg :

    2 level :

    -Fruit
    ---Red
    -----Cherry
    -----Strawberry
    -----Yellow

    1 level :

    Fruit
    ---Red

    what we have to do ?

  6. #81
    SitePoint Evangelist
    Join Date
    Jun 2003
    Location
    Melbourne, Australia
    Posts
    440
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Oth
    Where are the functions for adding/deleting nodes for the modified preorder tree traversal ?
    The following class has those features:
    http://dev.e-taller.net/dbtree/
    Zealotry is contingent upon 100 posts and addiction 200?

  7. #82
    SitePoint Enthusiast
    Join Date
    May 2001
    Posts
    26
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I just thought I'd mention another easy way to store hierarchical data with single-query extraction. This method uses a serial number for each node to extract its parent-relationship and node-depth.

    Our data:

    Fruit
    --Red
    ----Strawberry
    ----Cherry
    --Yellow
    ----Banana
    Meat
    --Quadroped
    ----Pork
    ----Beef
    --Biped
    ----Chicken
    ----Turkey

    Our serialization of the above tree would be:

    AA (Fruit)
    AAAA (Red)
    AAAAAA (Strawberry)
    AAAAAB (Cherry)
    AAAB (Yellow)
    AAABAA (Banana)
    AB (Meat)
    ABAA (Quadroped)
    ABAAAA (Pork)
    ABAAAB (Beef)
    ABAB (Biped)
    ABABAA (Chicken)
    ABABAB (Turkey)


    Each node consists of a two-character serial number, and incremented such as AA,AB,AC, etc. For each child node, you extend the serial number with two new characters, and increment it similarly for all children of the same node. In the database, you just store the serial number along with each node.

    To get all the children of a parent node, you select all serial values that match the parent on the left-hand side, (mysql) where serial like 'AA%' to get all children of the Fruit node. To get all children directly under a node, you have to take the length of the serial value into play, such as where serial like 'AA%' and length(serial) = 4. You also use order by serial to get the right order.

    With a two-character serial value, you are limited to the number of nodes per parent, although it should be more than enough. If not, just use a three-character serial value, or more.

    Notice how easy it is to add nodes to the tree, there is no need to update any of the other nodes to do so. I've used this method to maintain a category heirarchy with many many levels of nodes and it works well.

  8. #83
    Danno
    SitePoint Community Guest
    Mohrt, It isn't easy to add new nodes. What if you need to add a node between pork and beef?

  9. #84
    SitePoint Enthusiast
    Join Date
    May 2001
    Posts
    26
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Danno
    Mohrt, It isn't easy to add new nodes. What if you need to add a node between pork and beef?
    I think we used another mechanism to order the nodes on each level, like a priority field and/or the node name itself. I'll have to dig up the code and see how it was handled.

  10. #85
    SitePoint Member
    Join Date
    Sep 2006
    Posts
    1
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hi,

    Does somebody know how to get next result:

    (I am using same tree as in article):

    For example, I wand to target only "Cherry" node;

    Code:
    Food
    --Fruit
    ----Red
    -------Cherry
    ----Yellow
    ----..more Fruit
    --Meat
    --...more Food
    As can be seen here, I want to display only "Cherry" subtree in complete, and other leafs only in start. If some code need to be added in PHP, this will help too.

    regards

    Thanks in advance!

  11. #86
    Anonymous
    SitePoint Community Guest
    This article's been around for years, so either I'm missing something or this has already been mentioned a 1000 times...

    The adjacency list function at the beginning of the article implies that the displayed tree will be indented, but the code doesn't seem to support that idea!

    To do that, the function should read (for example):

    // display each child
    while ($row = mysql_fetch_array($result)) {
    echo "<br>";
    // indent and display the title of this child
    echo str_repeat("&nbsp;&nbsp;",$level).$row['title']."\n";

  12. #87
    NoepZor
    SitePoint Community Guest
    Is it possible with the second method to re-order the tree? I want to use it for an menu with one sublevel. Or is it better to use the first method? I'm using the first one now with a position column and a childposition column for ordering the childs.

  13. #88
    rko
    SitePoint Community Guest
    Has anybody been able to map the query that gets the tree to an array like:

    [fruit] => array(
    [sub-fruit] => array (
    [sub-sub-fruit1],
    [sub-sub-fruit2]
    )
    )

    That would be very usefull.

  14. #89
    Tim
    SitePoint Community Guest
    Interesting article! It seems to me that you could improve the INSERT performance of the modified preorder tree traversal by using floating-point "lft" and "rgt" fields instead of integers: each row in the DB now effectively stores a "range" which can be subdivided as much as you want when adding children. (The root item stores some fixed initial "range", say lft=0 and rgt=1.0.) This way, INSERTing a new item would be just a single INSERT operation, no UPDATEs required. The change would come at the cost of no longer being able to quickly count the number of items in a subtree, however I don't think this is too important for most applications, and all other operations are still just as fast.

  15. #90
    SitePoint Member
    Join Date
    Nov 2006
    Posts
    1
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hi,
    is it possible to take the whole data in an array like this:


    PHP Code:
    $categories = array(
    '0'=>array(// data id
                 
    0'=>array(), //level 0 
                 '
    1'=>array(  //level 1
                               '
    0'=>array(//level1 record 0),
                                '
    1'=>array(//level1 record 1),
                                '
    2'=>array(//level1 record 2)
                               )
                 '
    2'=>array(  //level 2
                                '
    0'=>array(//level2 record 0),
                                '
    1'=>array(//level2 record 1)
                                )
                 '
    3'=>array(  //level 3
                                '
    0'=>array(//level3 record 0),
                                '
    1'=>array(//level3 record 1),
                                '
    2'=>array(//level3 record 2)
                                )
    ), // key=0, first main category
    //and data id=2,3,4 ... and goes on
    ); 
    Thanks a lot...

  16. #91
    Anthony K
    SitePoint Community Guest
    Excellent article!! I have had this problem with recursion and trees for ages now, and this is a fantastic solution. I've implemented this on one my sites now and multiple queries that took close to 10 seconds before are now down to one query and 0.0081 query time using MySQL... thanks very much for the advice.

    Anthony K

  17. #92
    Mels Lenstra
    SitePoint Community Guest
    I've found a way to use the relatively simple recursive method *without* querying the database more than one time.
    It goes as follows: You simply do a single "SELECT * FROM table" query. Then you put all of that in an array:
    $sqltable = array();
    while($thisrow = mysql_fetch_assoc($result)){
    $sqltable[] = $thisrow;
    }
    And then you can use a recursive function on that array. It works beautifully and is very fast as it uses only one query. The overhead of using a recursive function is still there though but I find that to matter much less than multiple queries.

  18. #93
    SitePoint Wizard REMIYA's Avatar
    Join Date
    May 2005
    Posts
    1,351
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Mels Lenstra View Post
    I've found a way to use the relatively simple recursive method *without* querying the database more than one time.
    It goes as follows: You simply do a single "SELECT * FROM table" query. Then you put all of that in an array:
    $sqltable = array();
    while($thisrow = mysql_fetch_assoc($result)){
    $sqltable[] = $thisrow;
    }
    And then you can use a recursive function on that array. It works beautifully and is very fast as it uses only one query. The overhead of using a recursive function is still there though but I find that to matter much less than multiple queries.
    It is really worth considering. Better 1 query than 30-50-100-150 queries

  19. #94
    Gilles vd Hoven
    SitePoint Community Guest
    This is very nice stuff. However, i think that i found a little bug. What if you have thesame "node name" twice, and then try to get all items from the first node. This would screw up the build_tree() function, since you will also get all childs of the second item.

    This can be fixed by changing the query a bit, but i don't have enough experience with MPTT to do that ;)

  20. #95
    Dan Bemowski
    SitePoint Community Guest
    Gilles, the example in the article shows what to do for a single root node (food). What I did using this information is add a column to identify which items are my root nodes allowing me to have multiple root nodes. You can do this by adding a boolean field indicating weather or not the item is a root node using 1 and 0. No two root node names should be the same. In the first section of this article they are describing a food tree. In the example, "food" is the root node and the query will display everything for the food node based on the left and right node values. If you then add another root node such as "clothing", you would identify this in the table as a root node and anything under this would be identified by a different set of left and right node values. This will allow you to have "red" food and "red" clothing.

    How you deal with this is simple. You would have a function similar to this:

    function show_tree() {
    //Select all root nodes
    $results=mysql_query("SELECT title FROM tree WHERE root_node=1");
    //Loop through and display the trees for all root nodes
    while($row=mysql_fetch_assoc($results)) {
    //Now call the function described in the article
    display_tree($row['title']);
    }
    } //End function show_tree()

    This approach will let you have two items with the same node names under different root nodes without confusion.

    Hope this information helps all who read this.

  21. #96
    JOKERz
    SitePoint Community Guest
    Nice!!!
    Thanx for sharing

  22. #97
    Greg
    SitePoint Community Guest
    If you add a node to the bottom of the tree won't you have to reindex most of your database?

  23. #98
    ben
    SitePoint Community Guest
    Greg,

    You wouldn't re-index the table; the lft and rgt values aren't an index.

  24. #99
    Owen
    SitePoint Community Guest
    "Of course, in a real database, you'd use the numerical id of each node."

    Can you elaborate on that? A numerical id that refers to data in another table?

  25. #100
    Joey
    SitePoint Community Guest
    Using the MPTT method, is there an easy way using only SQL to get the first level children only?
    Example: for fruit, only return red and yellow


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •