Как написать "Похожие материалы"

jeno

Новичок
Как написать "Похожие материалы"

Добрый день.

Вот ломаю голову, решил спросить у вас) может быть что-то расскажете + наверное другим будет интересно.

Есть таблица с материалами, допустим:
id, title, text

Есть таблица с тегами к материалами:
id, name

Есть таблица с ссылками тег > материал (какой тег какому материалу принадлежит):
tag_id, material_id

Что необходимо:
На странице просмотра конкретного материала, необходимо снизу выводить "похожие материалы"
Ссылки на схожие материалы + очень желательно сортировать их по схожести... (схожесть я думал определять по тегам, чем больше общих тегов, тем более схожий материал)

И вот ломаю голову как это сделать =\ всетаки прошарить всю БД,пересчитать все теги и сравнить с тегами текущего материала, задача не простая...займет наверное не мало времени...

Как быть? или вообще этот механизм не подходит? (выборка похожих материалов по тегам)

Заранее спасибо!
 

Духовность™

Продвинутый новичок
DiMA
???


Ссылки просто на схожие материалы можно получить разными методами. Я вот так придумал, но ИМХО можно и оптимизировать:

[sql]
# допустим запросили статью с ID = 5
# нужно получить статьи по теме, с тегами, которые есть у статьи с ID = 5

select * from article
WHERE
article.id IN ( SELECT id_element FROM article_tag WHERE id_tag IN ( SELECT id_tag FROM article_tag WHERE id_element = 5 ))
[/sql]

а вот как сделать максимальную схожесть - это да, интересный вопрос.
 

zerkms

TDD infected
Команда форума
И вот ломаю голову как это сделать =\ всетаки прошарить всю БД,пересчитать все теги и сравнить с тегами текущего материала, задача не простая...займет наверное не мало времени...
вместо того, чтобы просто сидеть и ломать голову разве сложно было взять, написать запрос и точно убедиться - что всё работает быстро или медленно?
запрос примитивный - джоинами прибиваем записи с такими же тегами, группируем по id, сортируем по COUNT(*), ставим лимит, идём смотреть снукер под пиво.

triumvirat
на mysql этот запрос будет очень громко и сочно причмокивать.
 

Krishna

Продался Java
select * from order by rand() limit 10
о_О

jeno
И вот ломаю голову как это сделать =\ всетаки прошарить всю БД,пересчитать все теги и сравнить с тегами текущего материала, задача не простая...займет наверное не мало времени...
Просто рассматриваешь связи в обратном порядке. То есть, берешь список тегов для текущей статьи. Потом, по очереди, обходишь все теги этой статьи, для каждого составляя список относящихся к нему статей. Потом, этот список суммируешь воедино, учитывая отдельным полем кратность для статей встречающихся неоднократно. Ну и потом сортируешь по этому полю.

-~{}~ 02.07.09 18:20:

Ы, телефон, сцуко лишил меня права первой ночи ))

-~{}~ 02.07.09 18:22:

А почему оффтопик? о_О
 

jeno

Новичок
сделал пока так:

при редактировании материала, в столбик tags (создал такой столбик в таблице с материалами)

записываю ID тегов через пробел (+ по пробелу вначало и в конце)

в итоге, при просмотре материала выбираю похожие:

SELECT `title` FROM `materials` WHERE `tags` LIKE '% 11 %' || `tags` LIKE '% 12 %' || `tags` LIKE '% 53 %';

вроде бы быстро и точно) потом РНР'ней пересортировываю ссылки по кол. схожих тегов (чем больше одинаковым, тем выше), и вывожу 10 ссылок


но вот думаю будет ли нормально работать, когда в БД будет скажем 10000 материалов =\ если будет много похожих (например один тег будет практически везде), РНР будет все это пересортировывать и т.д. =\

буду очень признателен за ваши замечания! )
 

Krishna

Продался Java
Не будет нормально работать. Идея идиотская.
Использовать надо таблицу связей, которая у тебя УЖЕ ЕСТЬ!

Такие запросы крайне медленны, ибо не используют индексы. Ботай индексы, применительно к LIKE и строковым столбцам.

-~{}~ 02.07.09 18:30:

потом РНР'ней пересортировываю ссылки по кол. схожих тегов
ужас, ужас :)

сортировать надо всё средствами БД _исключительно_

-~{}~ 02.07.09 18:31:

На форуме с: Feb 2006
Cообщений: 129
Блин, чёта сразу не заметил)
Медицина тут бессильна :)
 

zerkms

TDD infected
Команда форума
а так запрос не будет выполнять задачу, озвученную в топике.

записываю ID тегов через пробел (+ по пробелу вначало и в конце)
жесть
сразу вообще все данные в одно поле зафигачь, через пробел. и автора, и дату, и текст...

но вот думаю будет ли нормально работать, когда в БД будет скажем 10000 материалов =\ если будет много похожих (например один тег будет практически везде), РНР будет все это пересортировывать и т.д. =\
и снова - вместо того, чтобы взять и попробовать - ты сидишь и думаешь... и думаешь и думаешь и думаешь...
 

zerkms

TDD infected
Команда форума
triumvirat
нужно найти похожие материалы к данной статье. где в твоём запросе указана "текущая статья" ?
твой запрос просто считает число тегов к каждой из статей.
разницу чуешь?
 

zerkms

TDD infected
Команда форума
triumvirat
после того, как ты добавишь where id = 666 будет выбрана только 1 запись. к ней будут прибиты её теги. а где похожие статьи? :)
 

iceman

говнокодер
triumvirat
такой запрос тока mysql похоже пропускает, я про group by и select *
 

zerkms

TDD infected
Команда форума
triumvirat
добавил where - выбралась только запись с where = 666
и?
 
Сверху