D
D
deleted-mezhevikin2011-05-14 14:17:52
Algorithms
deleted-mezhevikin, 2011-05-14 14:17:52

Tree comments

What is the best algorithm to organize tree-like comments with nesting level 2?
Is it reasonable to use tree building algorithms here?

Answer the question

In order to leave comments, you need to log in

7 answer(s)
A
Andrey Shaydurov, 2011-05-15
@deleted-mezhevikin

do not need any trees and parentID. because of them, you can run into JOINs or the problem of (n + 1) queries. everything is simpler:
1) select the attribute by which you sort the comments in the topic. for example this is created_at.
2) store created_at and parent_created_at for all comments. for root, set parent_created_at to created_at.
3) Selection ORDER parent_created_at DESC, created_at DESC receives comments in the right order
4) when rendering by checking parent_created_at is equal to created_at - without indent, not equal - with indent
5) ?????
6) PROFIT comment tree with max. nesting level equal to two

N
nixmale, 2011-05-15
@nixmale

If we are talking about SQL, then there is one very good solution for sorting tree-like comments into one SQL query without LEFT JOIN, by the way, which, using AJAX, allows you to reload separate branches starting with any comment in the chain.
Suppose adding comments to a topic looks like this:

$arr = array(
     array('id'=>1, 'pid'=>0, 'name'=>'Comment 1'),
      array('id'=>2, 'pid'=>1, 'name'=>'Comment 1.1'),
      array('id'=>3, 'pid'=>1, 'name'=>'Comment 1.2'),
      array('id'=>6, 'pid'=>1, 'name'=>'Comment 1.3'),
       array('id'=>4, 'pid'=>2, 'name'=>'Comment 1.1.1'),
       array('id'=>5, 'pid'=>2, 'name'=>'Comment 1.1.2'),
       array('id'=>7, 'pid'=>2, 'name'=>'Comment 1.1.3'),
     array('id'=>8, 'pid'=>0, 'name'=>'Comment 2'),
      array('id'=>12, 'pid'=>8, 'name'=>'Comment 2.1'),
      array('id'=>17, 'pid'=>8, 'name'=>'Comment 2.2'),
       array('id'=>13, 'pid'=>12, 'name'=>'Comment 2.1.1'),
        array('id'=>16, 'pid'=>13, 'name'=>'Comment 2.1.1.1'),
     array('id'=>9, 'pid'=>0, 'name'=>'Comment 3'),
      array('id'=>14, 'pid'=>9, 'name'=>'Comment 3.1'),
       array('id'=>15, 'pid'=>14, 'name'=>'Comment 3.1.1'),
     array('id'=>10, 'pid'=>0, 'name'=>'Comment 4'),
     array('id'=>11, 'pid'=>0, 'name'=>'Comment 5'),
     );

Each comment has an id and a parent id (pid). The answer to the topic should take pid = 0, and the answer to the comment - the id of the comment to which you are responding, respectively. The final tree should look like the one shown in the sample array.
To expand the tree in 1 SQL, it is enough to get all comments from the database that have a topic ID, sorting them like this: ORDER BY pid ASC, id ASC. As a result, we get the following array.
$arr = array(
     array('id'=>1, 'pid'=>0, 'name'=>'Comment 1'),
     array('id'=>8, 'pid'=>0, 'name'=>'Comment 2'),
     array('id'=>9, 'pid'=>0, 'name'=>'Comment 3'),
     array('id'=>10, 'pid'=>0, 'name'=>'Comment 4'),
     array('id'=>11, 'pid'=>0, 'name'=>'Comment 5'),
      array('id'=>2, 'pid'=>1, 'name'=>'Comment 1.1'),
      array('id'=>3, 'pid'=>1, 'name'=>'Comment 1.2'),
      array('id'=>6, 'pid'=>1, 'name'=>'Comment 1.3'),
       array('id'=>4, 'pid'=>2, 'name'=>'Comment 1.1.1'),
       array('id'=>5, 'pid'=>2, 'name'=>'Comment 1.1.2'),
       array('id'=>7, 'pid'=>2, 'name'=>'Comment 1.1.3'),
     array('id'=>12, 'pid'=>8, 'name'=>'Comment 2.1'),
      array('id'=>17, 'pid'=>8, 'name'=>'Comment 2.2'),
      array('id'=>14, 'pid'=>9, 'name'=>'Comment 3.1'),
      array('id'=>13, 'pid'=>12, 'name'=>'Comment 2.1.1'),
       array('id'=>16, 'pid'=>13, 'name'=>'Comment 2.1.1.1'),
       array('id'=>15, 'pid'=>14, 'name'=>'Comment 3.1.1'),
     );

Now we need to change the structure of the array.
     for ($i = 0, $c = count($arr); $i < $c; $i++)
     {
       $new_arr[$arr[$i]['pid']][] = $arr[$i];
     }

And the final recursion function.
     function my_sort($data, $parent = 0, $level = 0)
     {
       $arr = $data[$parent];

       for($i = 0; $i < count($arr); $i++)
       {
         echo '<div style="padding-left:' . $level . 'px;">';
         echo $arr[$i]['name'];
           if(isset($data[$arr[$i]['id']])) my_sort($data, $arr[$i]['id'], 20);
         echo '</div>';
       }
     }

Now, to show the entire tree at once, just call
my_sort($new_arr, 0);

S
shsmad, 2011-05-14
@shsmad

Well, if the nesting is 2 and will not increase and the sql-base will be used, then you can use the id / parent_id bundle, you can not use the path algorithms and nested set :) And if not sql, but say nosql (for example, mongodb), then there even easier.

K
Konstantin, 2011-05-14
@Norraxx

In this case, it is enough to keep only the parent of the comment, and then ask if there are comments with such a parent,
or
Do something like this:
auto-increment on id = 100, ty. 100, 200, 300, etc...
table:
id, level, comment
100, 1, "comment 1"
insert answers to the comment into the table from +1 to id.
101, 2, "comment to comment 1"

E
ertaquo, 2011-05-14
@ertaquo

Why not make nesting unlimited, but display the same for all levels above the first one?

A
Alexander, 2011-05-15
Yankovskiy @Suncheez

Most importantly, when you make a tree, make a discrete gradient in front of the comment so that you can easily see what level the comment is.
Because on Habré, for example, when a comment thread grows, sometimes you don’t understand who answers to whom.

E
Evgeny Bezymyannikov, 2011-05-16
@psman

phpclub.ru/detail/article/db_tree
is still worth studying nestedtree

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question