Как сравнить группу тегов с другим постом? s теги в моей базе данных, чтобы получить связанные сообщения?
Я пытаюсь сравнить группу тегов в сообщении с тегами другого сообщения , но не каждый тег в отдельности. Допустим, вы хотите получить действительно связанные элементы на основе тегов из поста, а затем показать их из наиболее связанных и наименее связанных. Каждый раз должно быть показано три связанных элемента, независимо от уровня отношений.
Пост A имеет теги: «архитектура», «дерево», «модерн», «швейцария»
Пост B содержит теги: «архитектура», «дерево», «модерн»
Пост C имеет теги: «архитектура», «модерн», «камень»
Пост D имеет теги: «архитектура», «дом», «резиденция»Пост B связан с постом A на 75% (3 связанных тега)
Сообщение C связано с сообщением A на 50% (2 связанных тегов)
Сообщение D связано с сообщением A на 25% (1 связанный тег)
Как я могу это сделать? В настоящее время я использую 3-таблицы .
posts
> id
> image
> date
post_tags
> post_id
> tag_id
tags
> id
> name
Я искал в Интернете и переполнении стека, чтобы узнать, как это сделать. Моя самая близкая находка была Как найти «связанные элементы» в PHP , но на самом деле это не решило много для меня.
ПРИМЕЧАНИЕ. Это решение предназначено только для MySQL, поскольку MySQL имеет собственную интерпретацию GROUP BY
. Я также использовал свой собственный расчет подобия. Я взял количество идентичных тегов и разделил его на среднее количество тегов в сообщении A и сообщении B. Итак, если сообщение A имеет 4 тега, а сообщение 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 ()
, чтобы выяснить, насколько разные массивы.
Но на самом деле решение Иварса сработало бы лучше, хотя это легче понять :)