У меня есть арт-сайт. Сейчас мне нужно показать родственные произведения искусства. У меня есть 3 таблицы:

art_info             : art_id, title  
art_tag_relationship : art_id, tag_id  
art_tags             : tag_id, tag (in text)

Я пытаюсь отсортировать родственное искусство для данного произведения искусства по наиболее релевантным совпадениям тегов.

Итак, теперь у меня есть 5 произведений искусства с бирками.

Теги арт # 1: красный, синий, зеленый, желтый
арт # 2 теги: красный, оранжевый, фиолетовый, черный, желтый, синий
арт # 3 теги: красный
арт # 4 теги: синий, зеленый
арт # 5 теги: белый, коричневый

Итак, теперь я хочу получить произведения искусства, наиболее близкие к искусству № 1, в порядке от наибольшего до наименьшего соответствия. Я хочу получить такие результаты

Связанное искусство с №1:

  • Наилучшее совпадение = арт # 2 (потому что он соответствует 3 тегам)
  • 2-е совпадение = арт # 4 (потому что совпадало 2 тега)
  • 3-е совпадение = арт № 3 (потому что он соответствует 1 тегу)
  • Не отображать иллюстрацию № 5, потому что совпадений не найдено.

Я думал об использовании оператора foreach, как только получу теги для рисунка №1, но это кажется неэффективным.

Вот запрос, который я использовал, чтобы получить теги для искусства №1.

SELECT art_info.art_id, art_info.title
FROM art_info
INNER JOIN art_tag_relationship ON art_info.art_id = art_tag_relationship.art_id
WHERE art_tag_relationship.art_id = '1'

Итак, теперь, когда у меня есть 4 тега из арта № 1, как мне получить наибольшее количество произведений искусства с наиболее связанными тегами?

Спасибо за ваше время и умение использовать мозги.

РЕДАКТИРОВАТЬ: Концепция кажется такой: получите теги для искусства № 1 через art_tag_relationship -> art_tags, затем получите art_id из art_tag_relationships, где tag_id совпадают с тегами, найденными для art_id № 1 в art_tag_relationships.

3
Darius 29 Авг 2011 в 08:41

2 ответа

Лучший ответ

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

SELECT 
    ai.art_id, 
    ai.title
    count(DISTINCT r2.tag_id) as relevance
FROM art_tag_relationship r1 
INNER JOIN art_tag_relationship r2 ON (r1.tag_id = r2.tag_id 
                                   AND r1.art_id <> r2.art_id) 
INNER JOIN art_info ai ON (r2.art_id = ai.art_id) 
WHERE r1.art_id = '1'   -- this is the art_id results should be related to. 
GROUP BY ai.art_id
ORDER BY relevance DESC
1
Johan 29 Авг 2011 в 12:08

Учитывая, что вы смотрите на произведение искусства art_id = 1000

SELECT 
    art_info.art_id, 
    art_info.title
    count(*) as Cnt
FROM 
    art_tag_relationship A1, 
    art_tag_relationship A2,
    art_info 
WHERE 
    A1.art_id = 1000 
    AND
    A1.tag_id = A2.tag_id 
    AND
    A2.art_id = art_info.art_id
GROUP BY 
    art_info.art_id
ORDER BY 
    Cnt DESC

(непроверено)

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

Поэкспериментируйте с концепцией и обновите свой пост, как только у вас появится рабочий запрос.

0
gahooa 29 Авг 2011 в 04:58