Цепочка комментариев с факторингом очков

Я бьюсь головой о что-то, и мне было интересно, может ли кто-нибудь более опытный, чем я, мне помочь.

Моя цель - создать цепочку комментариев, учитывающую систему оценки комментариев.

Сначала я объясню, где я сейчас нахожусь.

Допустим, у нас есть ветка комментариев к статье, которая выглядит как в примере ниже. Число в скобках - это идентификатор этого комментария. Идентификаторы присваиваются автоматически базой данных и увеличиваются в хронологическом порядке с каждым опубликованным дополнительным комментарием. Количество тире перед текстом комментария отражает глубину комментария.

(01)"This is a top level comment." 
(02)-"This is a second level comment. A reply to the top level comment above."
(06)-"This is also a second level comment / another reply to comment 01."
(07)--"This is a reply to comment 06."
(03)"This is a different top level comment."
(05)-"This is a reply to the comment above."
(08)--"This is a reply to that comment in turn."
(10)---"This is a deeper comment still."
(04)"This is one more top level comment."
(09)-"This is one more reply."

Моя первая проблема заключалась в хранении этих данных таким образом, чтобы их можно было вернуть в правильном порядке. Если вы просто сохраняете поле глубины и упорядочиваете по глубине, сначала будут возвращены все комментарии верхнего уровня, а затем комментарии второго уровня и т.д.

Один из способов добиться этого - сохранить полное происхождение каждого комментария.

Comment ID  | Parentage
     01     |              (Comment 01 has no parent because it is top level)
     02     | 01-          (Comment 02 was a reply to comment 01)
     03     | 
     04     |              
     05     | 03-
     06     | 01-
     07     | 01-06-       (Comment 07 has two ancestors 01 and then 06)
     08     | 03-05-
     09     | 04-
     10     | 03-05-08-

Добавить еще одну запись комментария так же просто, как взять Parentage из комментария, на который вы отвечаете, и добавить его ID для формирования нового родительского элемента. Например, если бы я отвечал на комментарий 10, я бы взял его происхождение (03-05-08-) и добавил его идентификатор (10-). База данных автоматически распознает его как 11-й комментарий, и мы получим:

Comment ID  | Parentage
     01     | 
     02     | 01- 
     03     | 
     04     |              
     05     | 03-
     06     | 01-
     07     | 01-06-
     08     | 03-05-
     09     | 04-
     10     | 03-05-08-
     11     | 03-05-08-10-

Теперь, когда мы заказываем комментарии для отображения, мы упорядочиваем конкатенацию родительского элемента и идентификатора комментария, что дает нам:

Order by CONCAT(Parentage, ID)

Comment ID  | Parentage    |   CONCAT(Parentage, ID)
     01     |              |   01-
     02     | 01-          |   01-02-
     06     | 01-          |   01-06-
     07     | 01-06-       |   01-06-07-
     03     |              |   03-
     05     | 03-          |   03-05-
     08     | 03-05-       |   03-05-08-
     10     | 03-05-08-    |   03-05-08-10-
     11     | 03-05-08-10- |   03-05-08-10-11-
     04     |              |   04-
     09     | 04-          |   04-09-

Что дает тот же список, что и впервые. Комментарий 11, который мы позже добавили, вставлен в правильное место:

(01)"This is a top level comment." 
(02)-"This is a reply to the top level comment."
(06)-"This is another reply that was posted later than the first."
(07)--"This is a reply to the second level comment directly above."
(03)"This is a different top level comment."
(05)-"This is a reply to the comment above."
(08)--"This is a reply to the comment above."
(10)---"This is a deeper comment still."
(11)----"THIS COMMENT WAS ADDED IN THE EARLIER EXAMPLE."
(04)"This is one more top level comment."
(09)-"This is one more reply."

Отступ можно сделать, проверив длину строки CONCAT и умножив len (CONCAT (Parentage, ID)) на заданное количество пикселей. Это здорово, у нас есть система хранения комментариев, которая распознает их происхождение.

Теперь проблема:

Не все комментарии равны. Чтобы отличать хорошие комментарии, необходима система оценки комментариев. Скажем, у каждого комментария есть кнопка «за» ... хотя мы хотим сохранить отцовство, если на один комментарий есть два прямых ответа на одном уровне, тогда мы хотим сначала показать тот, который набрал наибольшее количество голосов.Я добавлю несколько голосов в [квадратных скобках] ниже.

(01)"This is a top level comment." [6 votes]
(02)-"This is a reply to the top level comment." [2 votes]
(06)-"This is another reply that was posted later than the first." [30 votes]
(07)--"This is a reply to the second level comment directly above." [5 votes]
(03)"This is a different top level comment." [50 votes]
(05)-"This is a reply to the comment above." [4 votes]
(08)--"This is a reply to the comment above." [0 votes]
(10)---"This is a deeper comment still." [0 votes]
(11)----"THIS COMMENT WAS ADDED IN THE EARLIER EXAMPLE." [0 votes]
(04)"This is one more top level comment." [2 votes]
(09)-"This is one more reply." [0 votes]

В этом примере комментарии (01) и (03) относятся к верхнему уровню, но (03) имеет [50 голосов], а (01) имеет только [6 голосов]. (01) появляется выше только в силу того, что он был опубликован ранее и, следовательно, ему был назначен меньший идентификатор. Точно так же (02) и (06) являются ответами на (01), но их нужно переупорядочить, чтобы дать возможность тому, кто набрал наибольшее количество голосов (06), подняться на вершину.

Я полностью застрял в попытках достичь этого.

Я полагаю, что любое упорядочение / переупорядочивание и индексирование лучше выполнять при голосовании за комментарий, чем при загрузке страницы, чтобы время загрузки страницы могло быть как можно быстрее, но кроме этого я абсолютно не знаю!

Любые идеи или свет, которые вы могли бы пролить на возможные пути, действительно уменьшили бы нагрузку! Спасибо за вашу помощь, как всегда.

----------------------------------------------- ---------------------------------

Изменить: в ответ на решение @ Paddy,

Когда я запустите выражение, предложенное @Paddy ниже, на фиктивных данных, первая ошибка, которую я получаю:

"The ORDER BY clause is invalid in views, inline functions, derived tables, subqueries, and common table expressions, unless TOP or FOR XML is also specified." 

Это можно исправить, добавив SELECT «верхние 100 процентов» к определению рекурсивного члена. Как только это будет сделано, я получаю сообщение об ошибке:

'CommentTree' has more columns than were specified in the column list.

Эту проблему можно решить, добавив столбец «Уровень» в спецификацию CommentTree. Затем данные печатаются, но сначала возвращаются все комментарии верхнего уровня, а затем что-то похожее (но не соответствующее) правильному порядку сортировки.

Данные возвращаются в таком виде:

ParentId  |  CommentId  |  Comment  |  Vote  | Level
NULL      |      1      | Text here |   6    |  0
NULL      |      3      | Text here |   50   |  0     
NULL      |      4      | Text here |   2    |  0    
4         |      9      | Text here |   0    |  1    
3         |      5      | Text here |   4    |  1    
5         |      8      | Text here |   0    |  2    
8         |      10     | Text here |   0    |  3   
10        |      11     | Text here |   0    |  4    
1         |      2      | Text here |   2    |  1    
1         |      6      | Text here |   30   |  1     
6         |      7      | Text here |   5    |  2    

Я сделал что-то не так или @Paddy что-то пропустил? Примите мои извинения, рекурсивные функции для меня очень новы.

8
задан Taryn 19 November 2013 в 11:32
поделиться