Как найти записи с наиболее распространенными тегами, например связанные вопросы в StackOverflow

Мы можем пометить вопрос несколькими тегами на веб-сайте StackOverflow. Мне интересно, как найти наиболее похожие вопросы с помощью общих тегов.

Предположим, у нас есть 100 вопросов в базе данных, у каждого вопроса есть несколько тегов. Допустим, пользователь просматривает определенный вопрос, и мы хотим, чтобы система отображала связанные вопросы на странице. Критерий для соответствующего вопроса - у них есть наиболее общие теги.

Например: Вопрос 1 помечен тегами AAA, BBB, CCC, DDD, EEE.

Вопрос 2 относится к первому первому, потому что в нем также есть все эти 5 тегов. Вопрос 3 относится к топ-2, потому что у него всего 4 или 3 тега, которые есть у Questio1. ......

Итак, мой вопрос заключается в том, как спроектировать базу данных и быстро найти вопросы, связанные с вопросом 1. Большое Вам спасибо.


person Community    schedule 29.10.2008    source источник


Ответы (3)


Возможно что-то вроде:

select qt.question_id, count(*)
from   question_tags qt
where  qt.tag in
( select qt2.tag
  from   question_tags qt2
  where  qt2.question_id = 123
)
group by qt.question_id
order by 2 desc
person Tony Andrews    schedule 29.10.2008

Если вы можете гарантировать, что в вопросе нет повторяющихся тегов, вы можете сделать следующее:

SELECT
     QT2.question_id,
     COUNT(*) AS cnt
FROM
     Question_Tags QT1
INNER JOIN Question_Tags QT2 ON QT2.tag = QT1.tag AND QT2.question_id <> QT1.question_id
WHERE
     QT1.question_id = @question_id
GROUP BY
     QT2.question_id
ORDER BY
     cnt DESC

Если вы не можете гарантировать уникальность тегов в вопросе, то решение Тони Эндрюса подойдет. Он будет работать в любом случае, но вы должны сравнить производительность в вашей системе с этим методом, если вы можете гарантировать уникальность с помощью ограничений.

person Tom H    schedule 29.10.2008

Не совсем понимаю, что вы имеете в виду, но на странице тегов теги перечислены в порядке их популярности (по количеству отмеченных тегов).

Изменить: это касается SO или вашего собственного приложения? Если речь идет о вашем собственном приложении, удалите тег SO, так как он вводит в заблуждение.

Edit2: я бы сказал что-то вроде:

SELECT * FROM `questions` WHERE `tag` LIKE '%tagname%' OR (looped for each tag) LIMIT 5,0

Где 5 - это максимальный результат, который вы хотите вернуть (хотя бы для некоторой оптимизации). Возможно, не лучшее решение, но я видел, как оно работает.

Вы также можете попробовать LIKE совпадение, используя заголовок.

person Ross    schedule 29.10.2008