recursion - PostgreSQL recursive CTE million size tree select by dynamic rank with paging -


my goal create query can retrieve tree controlling depth , amount of items returned @ each depth sorted rank descending, rank changing.

i.e.

give me tree starting @ node id 4, maximum depth of 5 (starting @ node) 5 children max @ each level sorted descending rank.

so have tree structure:

create table thingtree (   id uuid not null,   parent_id uuid,   text character varying(2048) not null,   rank integer not null default 0,   constraint thingtree_pkey primary key (id),   constraint thingtree_parent_id_fkey foreign key (parent_id)       references thingtree (id) match simple       on update no action on delete no action ) 

i want select node id , children, configurable limit of records pulled @ each depth , sorted rank, changing.

so decided create data:

create extension "uuid-ossp"; create function build_tree (parent_id uuid,max_depth integer,current_depth integer,max_direct_children integer) returns boolean $$    declare     new_id uuid := uuid_generate_v4();     begin      if current_depth >= max_depth         return 0;     end if;      insert thingtree values (new_id, parent_id,'test',current_depth + 1);     in 0..(max_direct_children - 1) loop         perform build_tree(new_id,max_depth,current_depth + 1, max_direct_children);     end loop;       return 0;        end; $$ language plpgsql; 

i use function generate tree 5 deep 6 children on each depth

select build_tree(null ,5, 0 ,6); 

the above function may take 20 seconds run

next try recursively select data:

with recursive thingtrees (     select tt.id,1::int depth, tt.parent_id, tt.text, tt.rank thingtree tt id = '207f7c55-1c68-4f0e-9493-416b84b6a0a4'   union     select st.id, tts.depth + 1 depth, st.parent_id, st.text, st.rank          thingtrees tts     join      thingtree st      on (tts.id = st.parent_id)     tts.depth <= 5 order st.rank    ) select * thingtrees 

now depth fine, knows not go past 5, issue want maximum of 5 direct children each level of node in tree, result returns 6 (because i'm not limiting it).

the issue if limit recursive union cte:

with recursive thingtrees (     select tt.id,1::int depth, tt.parent_id, tt.text, tt.rank thingtree tt id = '207f7c55-1c68-4f0e-9493-416b84b6a0a4'   union     (select st.id, tts.depth + 1 depth, st.parent_id, st.text, st.rank          thingtrees tts     join      thingtree st      on (tts.id = st.parent_id)     tts.depth <= 5 order st.rank limit 5)    ) select * thingtrees 

the issue here returns first 5 sub nodes of tree instead of 5 each depth.


Popular posts from this blog