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

Как сравнить группу тегов с другим постом? 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 , но на самом деле это не решило много для меня.

7
задан Community 23 May 2017 в 12:27
поделиться

2 ответа

ПРИМЕЧАНИЕ. Это решение предназначено только для 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
4
ответ дан 7 December 2019 в 14:26
поделиться

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

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

0
ответ дан 7 December 2019 в 14:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: