Сравните группу тегов, чтобы найти сходство/оценку с помощью PHP/MySQL

Как сравнить группу тегов с другими тегами в моей базе данных для получения связанных сообщений?

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

Post A имеет теги: "архитектура", "дерево", "современный" , "швейцария" Post B имеет теги: "архитектура", "дерево", "современный" Post C имеет теги: "архитектура", "современный" , "камень" Post D имеет теги: "архитектура", "дом", "место жительства"

Сообщение B относится к сообщению A на 75% (3 связанных тега) Post C относится к сообщению A на 50% (2 связанных тега) Сообщение D связано с сообщением A на 25% (1 связанный тег)

Как я могу это сделать? В настоящее время я использую 3-таблицы.

posts
> id
> image
> date
post_tags
> post_id
> tag_id
tags
> id
> name

Я искал Интернет и переполнение стека, чтобы узнать, как это сделать. Моя ближайшая находка была Как найти "Связанные элементы" в PHP, но на самом деле это не помогло мне.

2 ответа

ПРИМЕЧАНИЕ. Это решение является только MySQL, поскольку MySQL имеет собственную интерпретацию GROUP BY

Я также использовал свой собственный расчет сходства. Я взял количество идентичных тегов и разделил их на средний счетчик тегов в post A и post B. Поэтому, если post A имеет 4 тега, а post B имеет 2 тега, которые оба разделены с A, сходство составляет 66%.

(SHARED:2 / ((A:4 + B:2)/2) или (SHARED:2) / (AVG:3)

Это должно быть легко изменить формулу, если вы хотите/нужно...

SELECT
 sourcePost.id,
 targetPost.id,
 /* COUNT NUMBER OF IDENTICAL TAGS */
 /* REF GROUPING OF sourcePost.id and targetPost.id BELOW */
 COUNT(targetPost.id) /
 (
 (
 /* TOTAL TAGS IN SOURCE POST */
 (SELECT COUNT(*) FROM post_tags WHERE post_id = sourcePost.id)
 +
 /* TOTAL TAGS IN TARGET POST */
 (SELECT COUNT(*) FROM post_tags WHERE post_id = targetPost.id)
 ) / 2 /* AVERAGE TAGS IN SOURCE + TARGET */
 ) as similarity
FROM
 posts sourcePost
LEFT JOIN
 post_tags sourcePostTags ON (sourcePost.id = sourcePostTags.post_id)
INNER JOIN
 post_tags targetPostTags ON (sourcePostTags.tag_id = targetPostTags.tag_id
 AND 
 sourcePostTags.post_id != targetPostTags.post_id)
LEFT JOIN
 posts targetPost ON (targetPostTags.post_id = targetPost.id)
GROUP BY
 sourcePost.id, targetPost.id


Поместите теги в массив. Каждый массив, соответственно, называется Post A/Post B и т.д. Затем используйте array_diff_assoc(), чтобы выяснить, насколько различны массивы.

Но действительно, решение Ivars будет работать лучше, это легче понять, хотя:)

licensed under cc by-sa 3.0 with attribution.