Реализация тега «многие ко многим» в mysql + полный список тегов - PullRequest
1 голос
/ 15 сентября 2010

на основе Как реализовать систему тегирования, аналогичную SO, в php / mysql?

Я внес небольшие изменения и получил следующую реализацию тега изображения:

SELECT I.imageId, GROUP_CONCAT(DISTINCT T.tagName SEPARATOR ' '), COUNT(*)<br> FROM Images I<br> INNER JOIN ImageTagMap M ON I.imageId = M.imageId<br> INNER JOIN ImageTags T ON T.tagId = M.tagId<br> WHERE T.tagName LIKE '%new%' OR T.tagName LIKE '%yo%'<br> GROUP BY I.imageId<br> ORDER BY COUNT(*) DESC

в настоящее время это успешно получает imageId всех этих изображений, которые заполняют предложение WHERE, и упорядочивает их в соответствии с большинством совпадений (нет совпадений, генерируемых предложением GROUP BY).он также получает все совпадающие имена тегов и помещает их в одну строку.хорошо.

что я действительно хотел бы для пользователя, так это иметь все tagNames для соответствующей картинки.в настоящее время возвращаются только те теги, которые соответствуют операторам LIKE.Например, если изображение помечено как «2010 Нью-Йорк», и я ищу (как указано выше) «Нью-йо», оно вернет imageId, «Нью-Йорк».но мне нужна вся информация о тегах для сопоставленного изображения, я хочу imageId, "new york 2010".

простое решение - вставить вышеуказанный запрос в подзапрос и повторно выполнить объединение с новым предложением WHERE.imageId IN (запрос выше как подзапрос).хотя это кажется глупым (даже если оптимизатор может творить с ним магию), конечно, мне не нужно повторять одно и то же соединение дважды?или я?

в сторону, есть ли лучший способ поиска по тегам, чем застрявший в куче LIKE?

Ответы [ 2 ]

1 голос
/ 15 сентября 2010

SELECT<br> M.imageId,<br> GROUP_CONCAT(DISTINCT T2.tagName SEPARATOR ' ') AS tagNames,<br> COUNT(DISTINCT T.tagName) AS relevance<br> FROM ImageTagMap M<br> JOIN ImageTags T ON T.tagId=M.tagId<br> JOIN ImageTagMap M2 ON M2.imageId=M.imageId<br> JOIN ImageTags T2 ON T2.tagId=M2.tagId<br> WHERE T.tagName LIKE '%new%' or T.tagName LIKE '%yo%'<br> GROUP BY M.imageId<br> ORDER BY relevance DESC

пришлось воссоединиться дважды.любые более короткие пути приветствуются.

0 голосов
/ 15 сентября 2010

Добавьте еще одну JOIN к используемой таблице ImageTags и объедините ее вместо той, с которой вы тестируете теги:

SELECT
    M.imageId,
    GROUP_CONCAT(DISTINCT Ta.tagName SEPARATOR ' ') AS tagNames,
    COUNT(DISTINCT Tc.tagName) AS relevance
FROM ImageTagMap M
JOIN ImageTags Tc ON Tc.tagId=M.tagId
JOIN ImageTags Ta ON Ta.tagId=M.tagId
WHERE Tc.tagName LIKE '%new%' OR Tc.tagName LIKE '%yo%'
GROUP BY M.imageId
ORDER BY relevance DESC

(я избавился от соединения с Images поскольку вы, похоже, не используете его.)

есть ли лучший способ поиска по тегам, чем застрявший в куче лайков?

Если выдействительно нужно произвольно сопоставлять подстроку с тегами, тогда нет, нет индексируемого способа сделать это.Проверка на равенство или фиксированная левая часть LIKE (т. Е. LIKE 'new yo%') будет гораздо более эффективной при наличии подходящих индексов.

...