From: | Paul Jungwirth <pj(at)illuminatedcomputing(dot)com> |
---|---|
To: | Martijn van Oosterhout <kleptog(at)svana(dot)org>, Gregory Taylor <gtaylor(at)gc-taylor(dot)com>, pgsql <pgsql-general(at)postgresql(dot)org> |
Subject: | Re: Recursive CTE trees + Sorting by votes |
Date: | 2014-08-07 15:57:31 |
Message-ID: | CA+6hpanROV3vJA+N0fgcxCwq9oonnq7W2PRG8fEYMUWNew+GQg@mail.gmail.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-general |
> Or another idea, add a column that is the path of the parent:
I don't think this will work. The problem is you need the full path to
keep the children with their parents, but you also need the score. If
you make the path an array of (-votes, id) tuples (perhaps flattened
for simplicity), then you get the correct ordering. That way at every
stage you are sorting by votes, but still keeping children with their
parents:
comments=> WITH RECURSIVE cte (id, message, author, path, parent_id,
depth, votes) AS (
SELECT id,
message,
author,
array[-votes,id] AS path,
parent_id,
1 AS depth, votes
FROM comments
WHERE parent_id IS NULL
UNION ALL
SELECT comments.id,
comments.message,
comments.author,
cte.path || -comments.votes || comments.id,
comments.parent_id,
cte.depth + 1 AS depth, comments.votes
FROM comments
JOIN cte ON comments.parent_id = cte.id
)
SELECT id, message, author, path, depth, votes FROM cte
ORDER BY path;
id | message | author | path | depth | votes
----+-----------------------------+--------+-------------------+-------+-------
5 | Very interesting post! | thedz | {-3,5} | 1 | 3
8 | Fo sho, Yall | Mac | {-3,5,-12,8} | 2 | 12
7 | Agreed | G | {-3,5,-5,7} | 2 | 5
6 | You sir, are wrong | Chris | {-3,5,-3,6} | 2 | 3
1 | This thread is really cool! | David | {-1,1} | 1 | 1
3 | I agree David! | Daniel | {-1,1,-4,3} | 2 | 4
2 | Ya David, we love it! | Jason | {-1,1,-3,2} | 2 | 3
4 | gift Jason | Anton | {-1,1,-3,2,-15,4} | 3 | 15
(8 rows)
Time: 0.966 ms
Paul
On Wed, Aug 6, 2014 at 2:38 PM, Martijn van Oosterhout
<kleptog(at)svana(dot)org> wrote:
> On Wed, Aug 06, 2014 at 05:28:09PM -0400, Gregory Taylor wrote:
>> We are working on a threaded comment system, and found this post by Disqus
>> to be super helpful:
>>
>> http://cramer.io/2010/05/30/scaling-threaded-comments-on-django-at-disqus/
>>
>> The CTE works wonderfully, and we're really happy with the results. The
>> last obstacle is figuring out how to sort by a "votes" field, meanwhile
>> preserving the tree structure.
>
> What do you mean exactly? Do you mean that want everything at the same
> level to be sorted by vote?
>
>> If we "ORDER BY path, votes" (assuming we have the same structure as in the
>> article), we never need tie-breaking on "path", so the "votes" part of this
>> doesn't even come into the equation.
>>
>> I suspect we need to do some path manipulation, but I'm not too sure of
>> where to begin with this. I attempted incorporating "votes" into the path,
>> but I failed pretty badly with this. It's probably way off, but here's my
>> last (failed) attempt:
>>
>> https://gist.github.com/gtaylor/e3926a90fe108d52a4c8
>
> I think what you need to do is do the ordering withing the CTE itself.
> Something like:
>
> WITH RECUSIVE cte () AS (
> SELECT ... ORDER BY vote DESC
> UNION ALL
> SELECT ... JOIN cte ... ORDER BY vote DESC
> ) SELECT * from cte;
>
> Or another idea, add a column that is the path of the parent:
>
> WITH RECUSIVE cte () AS (
> SELECT array[] as path_parent, array[id] as path, ... ORDER BY vote DESC
> UNION ALL
> SELECT cte.path as path_parent, cte.path || comments.id as path, ... JOIN cte ... ORDER BY vote DESC
> ) SELECT * from cte order by path, votes desc;
>
> Hope this helps,
> --
> Martijn van Oosterhout <kleptog(at)svana(dot)org> http://svana.org/kleptog/
>> He who writes carelessly confesses thereby at the very outset that he does
>> not attach much importance to his own thoughts.
> -- Arthur Schopenhauer
>
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.4.10 (GNU/Linux)
>
> iQIVAwUBU+KgXUvt++dL5i1EAQgKzQ//fWqd56vcwKsYQDtbUE3Q2/ohUinYxpb6
> HgS9HoEs8QU3b4yzE6VOVXcUcN3/z6PPx4Mz3rqFOVgsFcZR2umGAaVw5oEr57Bd
> mqFDVgUxq8Xio2tijO0XFU89fh+/Cvus08CRh+OH6POLe6M76ox6cmFPtQzeaEon
> iFKXZZRIzFv7zpoE3xsQ7wgqSF44L0TIJIjdw3Dhcs8fN+T/jO0hJtUMKidGwbbv
> 9f08r9kjSMBYAhKCPXZHy/By/E91DhA8GjJFL1MloHPol/lzSkn7v7amWJZaILyE
> g3ghGUG1YhPJPA3Dw2VBKWzumNyu8kXSzTvzN6PacFToCf2ZIfTJH59ehPqztt0o
> FC6auCvO1vWS3NbOKSwdBVvXb/bJsIM3uqN16LSVhHqUp75eOFp5AWKJMCjQF1hE
> MkHk5xyz2CWsYZTlzqCKtGxRjFEbxKGjtqsxcM4qKM3uSjMG/ZhaAY6FZFLIage0
> yxsHrE5N+zfDAGV1EplxxtzMHUEqyFnBYQNRHUSChLPCkgrluOeFFRQU22aVpUUL
> vbPIBI8E16bbtU6zwnE3DoMdBm1Pq5E4c+URbfbzJhGB1e/DkDqf7pOZjojLJ9ue
> DRP777bBbsYwtCdS69kiIDkfwA2f7lliILI9wpnKSg64SIWlCR6NVWFTsfU8OP4l
> cJw8kApkDr4=
> =8bEW
> -----END PGP SIGNATURE-----
>
--
_________________________________
Pulchritudo splendor veritatis.
From | Date | Subject | |
---|---|---|---|
Next Message | Adrian Klaver | 2014-08-07 16:10:46 | Re: order by question |
Previous Message | Kevin Grittner | 2014-08-07 15:36:28 | Re: order by question |