Форум программистов, компьютерный форум, киберфорум
PHP: базы данных
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.58/19: Рейтинг темы: голосов - 19, средняя оценка - 4.58
6 / 6 / 1
Регистрация: 25.07.2009
Сообщений: 49

Поиск по тегам (с чекбоксами)

05.11.2010, 21:38. Показов 4185. Ответов 17
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
здравствуйте. есть таблица, содержащая ид статьи и ид тега. есть страничка, на ней имеется набор чекбоксов, соответствующих тегам. необходимо реализовать поиск статей, удовлетворяющих лишь выбранным тегам (чекбоксам). одна статья может быть ассоциирована с несколькими тегами.

например, таблица:
Code
1
2
3
4
5
6
ид статьи | ид тега
1 | 1
1 | 2
2 | 3
3 | 1
3 | 3
при поиске по тегам 1 и 2, код должен вернуть номера статей: 1 и 3.

сам я реализовал поиск с использованием INNER JOIN, вот только при увеличении количества тегов, запрос становится длиннее и это сильно сказывается на производительности компа. возможно я как-то неправильно его реализовал...

вот пример моего запроса для трех тегов (1,4,5):
SQL
1
SELECT A.news_id FROM news_tags A INNER JOIN news_tags B INNER JOIN news_tags C ON A.news_id=B.news_id AND A.news_id=C.news_id WHERE A.tag_id=1 AND B.tag_id=4 AND C.tag_id=5
есть ли другой вариант реализации подобного поиска, но с меньшими затратами времени и ресурсов?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
05.11.2010, 21:38
Ответы с готовыми решениями:

Поиск по тегам в БД
Здравствуйте форумчане. Хочу сделать для новостного сайта в каждой новости имеющей список тегов, ID похожих по тегам новостей. Дабы...

Поиск по тегам или расширенный поиск
Вечер добрый. Подскажите пожалуйста как реализовать поиск по тегам. Хотя бы алгоритм. Например: автомобиль у него есть характеристики...

Поиск по тегам
подскажите как сделать поиск по тегам , к примеру ... В папке с программой есть файл Word.txt , в нём : Биография автора . ( ...

17
 Аватар для Nazz
898 / 729 / 80
Регистрация: 12.03.2009
Сообщений: 2,804
Записей в блоге: 2
05.11.2010, 22:19
а так:

SQL
1
SELECT * FROM `table_mame` WHERE `news_tags` IN (1,2)
0
6 / 6 / 1
Регистрация: 25.07.2009
Сообщений: 49
05.11.2010, 23:51  [ТС]
Цитата Сообщение от Nazz Посмотреть сообщение
а так:

SQL
1
SELECT * FROM `table_mame` WHERE `news_tags` IN (1,2)
сори, я долго пытаюсь придумать и уже сам запутался. я не правильно написал пример.
Code
1
2
3
4
5
6
ид статьи | ид тега
1 | 1
1 | 2
2 | 3
3 | 1
3 | 3
при поиске по тегам 1 и 2 должно вернуть только 1 статью, т.е. надо найти только те статьи, которые связаны со каждым из выбранных тегов (И, а не ИЛИ).
0
 Аватар для Nazz
898 / 729 / 80
Регистрация: 12.03.2009
Сообщений: 2,804
Записей в блоге: 2
06.11.2010, 13:17
что естли попробівать так:
SQL
1
SELECT * FROM `table_mame` WHERE `news_tags`=1 AND `news_tags`=2
0
 Аватар для suharik
261 / 247 / 57
Регистрация: 03.09.2010
Сообщений: 805
06.11.2010, 14:15
Я делал через 2 форича, после обычного запроса в такую таблицу.
0
6 / 6 / 1
Регистрация: 25.07.2009
Сообщений: 49
06.11.2010, 14:20  [ТС]
Цитата Сообщение от Nazz Посмотреть сообщение
что естли попробівать так:
SQL
1
SELECT * FROM `table_mame` WHERE `news_tags`=1 AND `news_tags`=2
это тоже самое что и ваш предыдущий вариант

Цитата Сообщение от suharik Посмотреть сообщение
Я делал через 2 форича, после обычного запроса в такую таблицу.
можно поподробнее? я не понял.
0
 Аватар для suharik
261 / 247 / 57
Регистрация: 03.09.2010
Сообщений: 805
06.11.2010, 14:28
Делаем запрос в бд

PHP
1
2
3
4
5
6
7
8
9
10
$sql = mysql_query("SELECT * FROM myTable");
$row=mysql_fetch_array($sql);
 
foreach ($row AS $key=> $value){
  foreach ($row1 AS $key1=> $value1){
    if ($value['idnews'] == $value1['idtags']){
     echo ....; // моя статья
    }
   }
}
как то так.
Возможно этот код задачу не решит, зато он поможет понять мою мысль о выводе нужной статьи через 2 форича.


Да кстати вожможны проблемы со значениями. тогда нужно поменять if ($value['idnews'] == $value1['idtags']){ на if ($key['idnews'] == $key1['idtags']){

Не по теме:

)) Не помню просто как там я точно делал.

0
6 / 6 / 1
Регистрация: 25.07.2009
Сообщений: 49
06.11.2010, 14:53  [ТС]
Цитата Сообщение от suharik Посмотреть сообщение
Делаем запрос в бд

PHP
1
2
3
4
5
6
7
8
9
10
$sql = mysql_query("SELECT * FROM myTable");
$row=mysql_fetch_array($sql);
 
foreach ($row AS $key=> $value){
  foreach ($row1 AS $key1=> $value1){
    if ($value['idnews'] == $value1['idtags']){
     echo ....; // моя статья
    }
   }
}
как то так.
Возможно этот код задачу не решит, зато он поможет понять мою мысль о выводе нужной статьи через 2 форича.


Да кстати вожможны проблемы со значениями. тогда нужно поменять if ($value['idnews'] == $value1['idtags']){ на if ($key['idnews'] == $key1['idtags']){

Не по теме:

)) Не помню просто как там я точно делал.

тут такое дело, на самом деле у меня несколько таблиц: одна таблица с содержимым статей и другая - связь статей и тегов. в 1 запросе можно было бы получить все нужные значения. в вашем примере мне придется считать всю таблицу связей (а записей там дофига) + создавать дополнительно запрос к первой таблице, в котором получать содержимое статей. по-моему не лучший вариант.

есть еще идеи?
0
 Аватар для Nazz
898 / 729 / 80
Регистрация: 12.03.2009
Сообщений: 2,804
Записей в блоге: 2
06.11.2010, 15:08
а зачем вам создавать две таких таблицы? почему бы просто не создать в таблице с содержимым статей поле для тегов?
0
6 / 6 / 1
Регистрация: 25.07.2009
Сообщений: 49
06.11.2010, 15:31  [ТС]
Цитата Сообщение от Nazz Посмотреть сообщение
а зачем вам создавать две таких таблицы? почему бы просто не создать в таблице с содержимым статей поле для тегов?
и как вы представляете себе структуру такой таблицы?
0
 Аватар для Nazz
898 / 729 / 80
Регистрация: 12.03.2009
Сообщений: 2,804
Записей в блоге: 2
06.11.2010, 15:59
Цитата Сообщение от NET_Goblin Посмотреть сообщение
и как вы представляете себе структуру такой таблицы?
id - int
name - varchar
date - date
full_news - text
short_news - varchar
author - varchar
tags_id - varchar(записывать так: 1,2,5,7)
0
6 / 6 / 1
Регистрация: 25.07.2009
Сообщений: 49
06.11.2010, 17:38  [ТС]
Цитата Сообщение от Nazz Посмотреть сообщение
id - int
name - varchar
date - date
full_news - text
short_news - varchar
author - varchar
tags_id - varchar(записывать так: 1,2,5,7)
а поиск по тегам тогда только через like %tag_id%, а это сравнение строк, значит дофига ресурсов будет съедать. вы про нормализацию слышали?
0
 Аватар для Nazz
898 / 729 / 80
Регистрация: 12.03.2009
Сообщений: 2,804
Записей в блоге: 2
06.11.2010, 18:00
попробйте так, но я не тестил, тут наклепал....


PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$query="SELECT * FROM table_name WHERE `news_tags`=1";
$result=mysql_query($query);
$a="";
for ($i=0;$i=mysql_num_rows($result))
{
$r=mysql_fetch_array($result);
$query1="SELECT * FROM table_name WHERE `news_tags`=2 AND `news_id`='".$r['id']."'";
$result1=mysql_query($query1);
if (mysql_num_rows($result1)!=0)
{
$r1=mysql_fetch_array($result1);
echo $r1['news_id']."<br />";
}
mysql_query($query1) or die(mysql_error());
}
0
6 / 6 / 1
Регистрация: 25.07.2009
Сообщений: 49
06.11.2010, 20:44  [ТС]
Цитата Сообщение от Nazz Посмотреть сообщение
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$query="SELECT * FROM table_name WHERE `news_tags`=1";
$result=mysql_query($query);
$a="";
for ($i=0;$i=mysql_num_rows($result))
{
$r=mysql_fetch_array($result);
$query1="SELECT * FROM table_name WHERE `news_tags`=2 AND `news_id`='".$r['id']."'";
$result1=mysql_query($query1);
if (mysql_num_rows($result1)!=0)
{
$r1=mysql_fetch_array($result1);
echo $r1['news_id']."<br />";
}
mysql_query($query1) or die(mysql_error());
}
уточню структуру базы:
таблица news содержит полное описание статьи (ид, заголовок, дата публикации, текст ...)
таблица tags содержит всевозможные теги (ид, строковое название, количество статей связанных с этим тегом)
таблица news_tags - связи статей и тегов (ид статьи, ид тега).
выбрать данные из таблиц статей и тегов я сам могу. основная проблема связана именно с выбором ид статей, связанных в точности со всеми (логическое И) выбранными пользователем тегами.

из вашего кода следует, что в 1 строке из таблицы связей статья-тег я получу ид статей, связанных с тегом 1. затем пробегая по массиву (строка 4), я выберу что-то связанное с тегом 2 и имеющее ид статьи равное тому, что было выбрано в строке 1. а какова вероятность что статья с тегом 1 будет также связана с тегом 2? как насчет еще 10 выбранных пользователем тегов? их придется дописать во вложенные циклы for. и еще, индикация тегов может иметь пропуски, т.е. ид тегов = {1,2,3,6,8,9,10,15...}.
благодарен за труды, но вариант не годится.
0
6 / 6 / 1
Регистрация: 25.07.2009
Сообщений: 49
09.11.2010, 19:17  [ТС]
народ, неужели никто подобного не писал?
0
lexxpavlov
27.11.2010, 10:50
Поиск по тегам с указанием количества совпадений тегов
SQL
1
2
3
4
5
6
7
SELECT
 id, COUNT(*) AS weight
FROM tag_links
WHERE
 tag IN (1,2,3)
GROUP BY id
ORDER BY weight DESC
Если нужно железно по всем тегам, то убрать ORDER BY и добавить
SQL
1
2
3
4
5
6
7
SELECT
 id, COUNT(*) AS weight
FROM tag_links
WHERE
 tag IN (1,2,3) AND
 weight = 3
GROUP BY id
В php будет так:
PHP
1
2
3
$tags = array(1,2,3);
$res = mysql_query("SELECT id, count(*) as weight FROM tag_links WHERE tag IN (".implode(',',$tags).") AND weight = ".count($tags)." GROUP BY id");
while ($line = mysql_fetch_assoc($res)) $articles[] = $line['id'];
6 / 6 / 1
Регистрация: 25.07.2009
Сообщений: 49
27.11.2010, 13:07  [ТС]
Цитата Сообщение от lexxpavlov Посмотреть сообщение
Если нужно железно по всем тегам, то убрать ORDER BY и добавить
SQL
1
2
3
4
5
6
7
SELECT
 id, COUNT(*) AS weight
FROM tag_links
WHERE
 tag IN (1,2,3) AND
 weight = 3
GROUP BY id
а что у вас за версия мускула? у меня ошибка - не понимает что за weight в 6й строке =(

Добавлено через 12 минут
upd/
исправил запрос (как ваш запрос работает у вас не возьму в толк, в мануале по мускулу строго написано что нельзя использовать псевдонимы в условиях):
SQL
1
2
3
4
5
6
7
8
SELECT
 id, COUNT(*) AS weight
FROM tag_links
WHERE
 tag IN (1,2,3) AND
 weight = 3
GROUP BY id
HAVING weight = 3
а вообще, lexxpavlov, большое спасибо!
0
lexxpavlov
27.11.2010, 16:37
О, точно. Конечно, нельзя использовать. Он ведь сначала делает WHERE, а только потом GROUP. Поэтому нельзя использовать в WHERE агрегированные столбцы.
Я у себя использую первый вариант, второй так написал, без проверки.
Получить только те, что нужно, можно либо через HAVING, либо на стороне php.
В столбце weight находится количество совпавших тегов из списка тегов.
Соответственно, при weight=3 - строгое соответствие всем трем тегам.
Сколько тегов передано - такое же максимальное значение weight.
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
27.11.2010, 16:37
Помогаю со студенческими работами здесь

Поиск по тегам в БД
Попросили меня сделать поиск по тегам, чтобы при внесении данных можно было к записи написать теги(ключевые слова), которые потом...

Поиск по тегам
Все ещё делаю image board и тут дело дошло до поиска по телам. Сначала я вытаскивал из базы все I'd картинок где есть нужные теги. Но...

Живой поиск по тегам
Здравствуйте! В базе mysql у меня есть столбец с тегами. id | name | tegi | ...

Поиск по нескольким тегам в ManyToMany
Есть две таблицы с m2m отношением + таблица связей (book -&gt; book_mark &lt;- mark). Я пытаюсь найти все книги, у которых есть заданный список...

Поиск элемента по не стандартным тегам
Добрый день, подскажите плииииз. В разных фреймворках встречал &quot;индексирование&quot; элементов по не системным тегам. (Angular, Vue) ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
Новые блоги и статьи
Программная установка даты и запрет ее изменения
Maks 02.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: при создании документов установить период списания автоматически. . .
Вывод данных в справочнике через динамический список
Maks 01.04.2026
Реализация из решения ниже выполнена на примере нетипового справочника "Спецтехника" разработанного в конфигурации КА2. Задача: вывести данные из ТЧ нетипового документа. . .
Функция заполнения текстового поля в реквизите формы документа
Maks 01.04.2026
Алгоритм из решения ниже реализован на нетиповом документе "ВыдачаОборудованияНаСпецтехнику" разработанного в конфигурации КА2, в дополнении к предыдущему решению. На форме документа создается. . .
К слову об оптимизации
kumehtar 01.04.2026
Вспоминаю начало 2000-х, университет, когда я писал на Delphi. Тогда среди программистов на форумах активно обсуждали аккуратную работу с памятью: нужно было следить за переменными, вовремя. . .
Идея фильтра интернета (сервер = слой+фильтр).
Hrethgir 31.03.2026
Суть идеи заключается в том, чтобы запустить свой сервер, о чём я если честно мечтал давно и давно приобрёл книгу как это сделать. Но не было причин его запускать. Очумелые учёные напечатали на. . .
Модель здравосоХранения 6. ESG-повестка и устойчивое развитие; углублённый анализ кадрового бренда
anaschu 31.03.2026
В прикрепленном документе раздумья о том, как можно поменять модель в будущем
10 пpимет, которые всегда сбываются
Maks 31.03.2026
1. Чтобы, наконец, пришла маршрутка, надо закурить. Если сигарета последняя, маршрутка придет еще до второй затяжки даже вопреки расписанию. 2. Нaдоели зима и снег? Не надо переезжать. Достаточно. . .
Перемещение выделенных строк ТЧ из одного документа в другой
Maks 31.03.2026
Реализация из решения ниже выполнена на примере нетипового документа "ВыдачаОборудованияНаСпецтехнику" с единственной табличной частью "ОборудованиеИКомплектующие" разработанного в конфигурации КА2. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru