Comments 44
Автор подымает один из самых больных вопросов: на сайтах можно найти поиском только по одному тэгу, а так, чтобы найти одновременно хотя бы два тэга (не говоря, чтобы показать по тэгу за минусом какого-то третьего) — уже никак. В результате либо ты лопатишь гору лишней информации, просматривая один тэг, либо сразу уходишь в поисковик.
У меня есть алгоритм вывода статей по тегам именно так — задаются три тега, и вначале выводятся все статьи со всеми тремя совпадающими, потом выводятся все статьи с совпавшими любыми двумя тегами, и потом уже выводятся все статьи, в которых один из представленных тегов. Причём делает это за один SQL-запрос.
Вариант для поиска номеров статей:
SELECT id, count(*) as weight FROM tag_links 
WHERE tag IN (1,2,3) GROUP BY id ORDER BY weight DESC

Вариант для вывода списка статей:
SELECT articles.id, articles.title FROM tag_links, articles 
WHERE tag_links.id=articles.id AND tag_links.tag IN (1,2,3) 
GROUP BY tag_links.id ORDER BY count(*) DESC

Если интересно, могу написать статью про то, как шёл к этому решению. Ничего выдающегося, в общем-то, но боюсь, здесь в комменте это затеряется…
Всего три таблицы — articles, tags и tag_links, реализующая связь многие-ко-многим первых двух таблиц.
Таблица articles: id, title, body
Таблица tags: id, name
Таблица tag_links: id, tag
Вы это сейчас на какой вопрос отвечали?

Я правильно догадываюсь, что на первый вопрос — ответ «да»?
м-м-м… да, простите. Верно, tag_links.tag — идентификатор тега, tag_links.id — это идентификатор статьи.
1, 2, 3 — айдишники искомых тегов. Их может быть и больше трёх.
Громковато это называть «алгоритм», ИМХО… действительно, ничего выдающегося.
согласен. Зато работает. А в своё время я не нашёл ничего готового, кроме посылания запросов в цикле и последующей обработки и сортировки.
Нельзя исключить какой-то тег.
Сложного в реализации поиска по нескольким тегам ничего нет, поэтому и непонятно почему нигде такого нет. А потом и появляются «никто не читает теги».
что значит Нельзя исключить какой-то тег? Уберите из запроса ненужный тег и найдите заново.
Нет, мне нужно «всё вот это», но чтоб «вот этого» ни в каком виде не было.
а, я понял. Верно, эти запросы такую выборку сделать не позволят. Нужно подумать, как это сделать. На крайний случай — отдельным вторым запросом.
так не получится — SELECT вначале отбирает записи, и только потом группирует и сортирует их. А так как в записи только одно поле tag, то NOT IN точно не сработает, потому что после первого условия там записи с полем tag из первого списка.
Я осознал это и удалил комментарий, когда вашего ответа еще не было, извините)
да ладно. Пусть будет мой ответ для других.
К тому же, у вас не глупость. Я вот тоже хочу так писать — WHERE tag IN (:includedTags) AND tag NOT IN (:excludedTags). Возможно, получится разработать такую структуру таблицы tag_links, чтобы такой запрос сработал (что вряд ли), или составить запрос по другому, например, через самопересечение этой таблицы.
Самым простым способом будет считать исключаемые теги отдельно (включив их в IN) и если их больше 0 — отбрасывать эти результаты.
SELECT id FROM tag_links WHERE tag IN (1,2,3) 
AND id NOT IN (SELECT id FROM tag_links WHERE tag IN (4,5,6))
GROUP BY id ORDER BY count(*) DESC
Написал статью про реализацию тегов в SonataAdminBundle, вставил эти запросы в конец статьи. Не стал отдельной статьёй постить.
Размышления на тему привели к такому решению:
1. Когда пользователь добавляет тег к статье, сохранять не только сам тег, но и раздел, в который публиковалась данная статья.
2. Если пользователь, читающий определенную статью, кликнет по такому тегу, мы сможем выдать ему только те материалы, которые содержат данный тег + имеет привязку к этому тому же разделу, что и та статья, в которой он по нему кликнул.

На счет умного поиска. Очень красивое решение, но пользователь может интересоваться сегодня шоколадками, а завтра колонизацией Марса.
А что в итоге с тем стартапом которому Вы свои тексты посвятили? Там bad request какой то.
Я обычно ставлю много тегов, с тем, чтобы потом можно было просматривать связанные статьи. Добавление 2-3 тегов не даёт практически ничего, нужно ставить десяток тегов.
Но это плохо работает, если нет механизма поиска по нескольким тегам. Даже больше, если этого механизма нет, то теги сильно уступают рубрикам. В принципе, в статье об этом и написано…
Выше вы описывали внутренности своего механизма поиска, как и что устроено «под капотом». А можно где-то посмотреть в действии или это не публичный проект?
В этом комментарии я больше говорил про личные записи. В частности, в Evernote в заметках я указываю 2-3 тега-рубрики (работа, проект, 2014) и пяток тегов, относящихся конкретно к этой заметке. После этого очень удобно их искать, и проблема тега «покрытие» из статьи исчезает, достаточно указать фильтры проект+игры или развлечение+игры, и найдутся разные заметки.
А сайт, на котором я использовал систему тегов, я вам в личку отправил.
Мы о том и пишем, что если побольше тегов, не только у сообщения, а вообще в системе, то можно проанализировать частотные связи между ними, и вообще говоря, взять на себя смелость экстраполировать запрос по «одному тегу», в запрос по «группе тегов особенно связанных с этим». Чем умнее мы метрику расстояния между тегами рассчитаем, тем более правильно будет работать система.
И не нужны будут «вычитания» тегов, или поиск по 2-3. Математика разрулит.
Всё равно нужны будут.
Математика может лишь помочь автоматически предлагать более умный выбор, что б такого ищущему предложить дописать в запрос, и что б такого пишущему приписать своей статье. Помочь модератору найти теги-синонимы, теги-подкатегории и т.п.
Теги, конечно же. читают. Иначе — зачем они тогда нужны? Хотя… искать по ним удобно.
По мне так, рубрики — это частный случай тэгов.

Разница только в организации пользовательского итнерфейса и структуры БД, связанная с принимаемыми ограничениями частного случая «рубрики» по сравнению с общим случаем «тэги».
Выскажусь про соотношение тегов и каталогов. С математической точки зрения, теги — это сетевая структура данных, то есть более общий случай категорий, которые лежат в иерархической модели. Поэтому, чтобы теги как минимум не проигрывали, должен быть модерируемый список тегов первого уровня, которые могли бы соответствовать категориям первого уровня, далее идет множество тегов второго уровня, которое соответствует подкатегориям. И в запасе еще остаются простые обычные привычные теги.
Мне кажется, что мы в этой статье предложили как все эти «уровни» отношений тегов вычислять, и тем самым сделать из тегового пространства вместо месива big bang, какие-то ассоциации и системы.

Наверное зря для математической части статьи не нарисовал красивых картинок. Придется повторить.
Думаю немногие сталкиваются с подобными темами и смогут по достоинству оценить всю прелесть это статьи. Но в любом случае, автору огромное спасибо и респект, вы попытались описать то, что ряду проектов хочется получить в виде технического решения, но, как правило, даже сформулировать задачу, которую вы описываете, является весьма сложно.
Only those users with full accounts are able to leave comments. Log in, please.