Ищем отправную точку для системы тегов

В основном я хочу настроить систему тегов, такую ​​как переполнение стека для записей, и попытаться спланировать, как будет работать поиск на основе релевантности. Я хочу иметь возможность отображать похожие записи с тегами для раздела связанных записей. Сейчас я использую две таблицы для тегов, таблицу для каждого уникального тега и таблицу соединений. Я пытаюсь понять, сработает ли это для создания списка записей с похожими тегами.

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


person gokujou    schedule 15.02.2010    source источник


Ответы (3)


добавить в таблицу сущностей еще одно поле: теги. со строкой тегов, разделенных запятыми, чтобы предотвратить еще 2 объединения для выбора списка сущностей.

person zerkms    schedule 15.02.2010
comment
Вы предлагаете хранить его в обоих местах и ​​просто использовать строку для поиска связанных записей? Прямо сейчас мой план по отсутствию тегов в таблице записей предназначен для быстрого и легкого поиска по тегам и для использования автозаполнения в поле ввода тегов наряду с другими возможными применениями. - person gokujou; 16.02.2010
comment
Я говорю об использовании строки ТОЛЬКО ДЛЯ извлечения сущностей, чтобы сделать запрос выбора более простым (и быстрым). По объединенной таблице поиск будет более эффективным. - person zerkms; 16.02.2010

Возможно, у вас была бы отдельная таблица для хранения связанных записей.

EntryId RelatedEntryId

Затем у вас может быть задание CRON, которое периодически пересчитывает отношения и обновляет таблицу. Это будет дешевле, чем пытаться вычислить эти отношения на лету.

person Stephen Curran    schedule 15.02.2010
comment
Думаю, я смогу это сделать. Любой намек на то, как их вычислить, или просто масса вытаскивания списков тегов и выполнения простых сравнений с ними, а затем сохранения их в этой новой таблице? Спасибо! - person gokujou; 16.02.2010
comment
Этот ответ дает SQL-запрос для поиска связанных элементов на основе общих тегов: stackoverflow.com/questions/246841/ Может быть, ваш Задание CRON может перебирать все записи, вычислять связанные записи с помощью этого запроса и сохранять их в вашей таблице. Я здесь не эксперт, так что, возможно, у кого-то есть лучшее решение :-) - person Stephen Curran; 16.02.2010

Вам нужно будет отслеживать, как часто один тег связан с другим. Например, предположим, что «php» и «mysql» имеют 50 общих статей (или что бы там ни было основное помеченное содержимое), в то время как «php» и «sql-server» могут иметь 3 статьи, а «php» и «apache» - 25 статей. учитывая «php», вы захотите вернуть «mysql» и «apache» в этом порядке (возможно, позволив «sql-server» отойти на второй план).

Ни в коем случае это не идеал, просто размышляя вслух (и как бы расширяя ответ Стивенса, теперь, когда я это вижу):

CREATE TABLE tag_relations (
tag_id int unsigned not null,
related_tag_id int unsigned not null,
relation_count smallint unsigned not null,
PRIMARY KEY (tag_id, related_tag_id),
KEY relation_count (relation_count)
);

Затем для каждого уникального тега, привязанного к статье, выполните цикл по всем другим тегам и INSERT / UPDATE, увеличивая Relationship_count на 1. Это означает, что ("php", "mysql") и ("mysql", "php") полностью совпадают. различные отношения должны поддерживаться, но, не копаясь в концепциях поиска, я, вероятно, забыл, он все равно будет работать. Если что-то имеет 10+ тегов, обновления будут очень медленными (возможно, передать это в cron, как предложил Stephenc), но таким способом будет проще искать. Красиво и прямо вот так:

SELECT related_tag_id, COUNT(relation_count) AS total_relations
FROM tag_relations
WHERE tag_id IN ([list,of,tag,IDs,to,compare])
// AND tag_id NOT IN ([list,of,tag,IDs,to,compare]) -- probably
GROUP BY related_tag_id
ORDER BY total_relations DESC

Это проще, чем проверять оба tag_id и related_tag_id и суммировать их, по крайней мере, с помощью множества подзапросов. ПРИСОЕДИНЯЙТЕСЬ к таблице тегов, чтобы получить актуальные имена тегов, и все готово.

Так что, если вы ищете «php» и «mysql», а «apache» часто относится к обоим, он будет в верхней части, поскольку он подсчитывает и взвешивает каждое общее отношение. Однако он не будет строго ограничивать его общими ссылками, поэтому добавьте HAVING total_relations >= x (x - произвольное отсечение) и / или просто обычный LIMIT x, чтобы все было актуально.

(примечание: изучите это, прежде чем подумать, что это хоть немного полезно - я уверен, что существует какой-то известный алгоритм, который в 100 раз умнее, и я просто не помню его.)

PHPro.org также имеет хорошую запись, используя похожая идея.

person tadamson    schedule 16.02.2010