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

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

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

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

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

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

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

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

ПРИМЕЧАНИЕ. Это решение – только 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 будет работать лучше, это проще понять, хотя 🙂