Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
PHP 5. На примерах. Авторы: Кузнецов М.В., Симдянов И.В., Голышев С.В. PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В. MySQL на примерах. Авторы: Кузнецов М.В., Симдянов И.В. Объектно-ориентированное программирование на PHP. Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель PHP 5 / 6 (3 издание). Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум MySQL

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: помогите доработать ключевые слова
 
 автор: dirol   (01.03.2011 в 17:35)   письмо автору
 
 

Помогите доработать вывод похожих новостей из базы данных

$dkwords - тут список ключевых слов при просмотре новости, и ниже выводятся новости в которых есть похожие ключевые слова.

К примеру добавили новость с ключевиками ( сша, россия, италия) если добавить еще новость с такими же ключевиками в том же порядке то все ок. а вот если в другом порядке то не выводит, и еще не выводит, ( россия, япония, сша)


<?php

    $sql2 
mysql_connect('localhost','root','');
    
mysql_query("SET NAMES cp1251");
    
mysql_select_db('en'$sql2);

   
$dkwords="сша, россия, италия";

       if (
$dkwords != "") {
       
$pohozih 2//по скольким словам искать
       
$statey 30//сколько статей показывать
       
$mass explode (", "$dkwords);
       
$flag10 0;
       if (
count($mass) < $pohozih) {$pohozih count($mass);}
       if (
$pohozih ==1) {$statey $statey 1;}
       
$dkwords0 "";
       foreach (
$mass as $key0 => $val0) {
            if (
$key0!=0) {$dkwords0 .=    " OR ";}
            
$dkwords0 .=    " keywords LIKE '%$val0%' ";
       }
       
$result2 mysql_query("SELECT keywords, id, title, UNIX_TIMESTAMP(time) as formatted FROM news WHERE time <= now() AND id<>'$id' AND keywords<>'' AND ( $dkwords0 ) ORDER BY time DESC"$sql2);
       if (@
mysql_num_rows($result2) > 0) {
       
$klink "";
       while (list(
$dkwords2$id2$title2$time2) = mysql_fetch_array($result2) AND $flag10 <= $statey) {
       
$mass2 explode (", "$dkwords2);
       
$pohozih2 0;
       foreach (
$mass as $key => $val) {
       if (
in_array($val$mass2) AND $pohozih2!=$pohozih) {
       if (
$pohozih2!=0) {$flag10++;}
       
$pohozih2++;

         if (
$pohozih2==$pohozih) {
            
$klink.= "<li><span>".date("d.m.Y, H:i"$time2)."</span>&nbsp;<a href=\"index.php?&id=$id2\">$title2</a></li>"; break;}

       }
      }
     }

    }

   }
echo 
"  $klink\n";
?>



CREATE TABLE IF NOT EXISTS `news` (
  `id` int(11) NOT NULL auto_increment,
  `cid` int(11) default '0',
  `title` varchar(299) default NULL,
  `time` datetime default NULL,
  `hometext` text,
  `status` int(1) NOT NULL default '0',
  `keywords` varchar(300) NOT NULL,
  PRIMARY KEY  (`id`),
  KEY `catid` (`cid`)
) ENGINE=MyISAM  DEFAULT CHARSET=cp1251 AUTO_INCREMENT=62 ;

INSERT INTO `news` (`id`, `cid`, `title`, `time`, `hometext`, `status`, `keywords`) VALUES
(31, 0, 'заголовок 1', '2011-03-01 17:29:26', NULL, 0, 'сша, россия, италия'),
(41, 0, 'заголовок 2', '2011-03-01 17:29:26', NULL, 0, 'сша, россия, италия'),
(51, 0, 'заголовок 3', '2011-03-01 17:29:26', NULL, 0, 'россия, сша, италия'),
(61, 0, 'заголовок 4', '2011-03-01 17:29:26', NULL, 0, 'италия, россия, сша');


к примеру в другой новости человек добавил другие ключевые слова

$dkwords="сша, россия, япония";


INSERT INTO `news` (`id`, `cid`, `title`, `time`, `hometext`, `status`, `keywords`) VALUES
(31, 0, 'заголовок 1', '2011-03-01 17:29:26', NULL, 0, 'сша, россия, италия'),
(41, 0, 'заголовок 2', '2011-03-01 17:29:26', NULL, 0, 'сша, россия, италия'),
(51, 0, 'заголовок 3', '2011-03-01 17:29:26', NULL, 0, 'россия, сша, италия'),
(61, 0, 'заголовок 4', '2011-03-01 17:29:26', NULL, 0, 'италия, россия, сша'),
(71, 0, 'пппппппппппппппппппппппп', '2011-03-01 17:36:51', 'ппппппппппппппппп', 0, 'россия, япония, курилы, италия'),
(81, 0, 'аааааааааааааа', NULL, NULL, 0, 'россия, курилы, япония');



а новости похожие по ключевым не выводятся

  Ответить  
 
 автор: cheops   (01.03.2011 в 17:44)   письмо автору
 
   для: dirol   (01.03.2011 в 17:35)
 

Для таких поисков лучше под ключевые слова выделить отдельную таблицу: одно ключевое слово - одна запись, и таблицу связи новостей с ключевыми словами. Одна строка хороша, когда вы выводите её в META-тэге HTML-страницы. Для операций поиска лучше таблицу нормализовать - логика поиска сразу упростится.

  Ответить  
 
 автор: dirol   (01.03.2011 в 17:47)   письмо автору
 
   для: cheops   (01.03.2011 в 17:44)
 

а если выведу в другую таблицу, пример поиска похожих и их вывод можете подскакать?

  Ответить  
 
 автор: cheops   (01.03.2011 в 17:57)   письмо автору
 
   для: dirol   (01.03.2011 в 17:47)
 

А вам самим там уже не сложно будет такой поиск организовать (если затруднения возникнут, конечно поможем). Вам достаточно будет вывести уникальные первичные ключи новостей из этой таблицы, для которых подходят ключевые слова
SELECT DISTINCT id_news FROM tbl
WHERE phrase IN ('сша', 'россия', 'италия')

А потом вывести новости с этими id_news, за исключением текущей новости
SELECT * FROM news
WHERE id_news IN SELECT DISTINCT id_news FROM tbl
WHERE phrase IN ('сша', 'россия', 'италия') AND id_news != 3
ORDER BY putdate DESC

PS У вас в зависимости от реализации и количества таблиц, каждое ключевое слово будет связано с одной из новостей, поэтому искать их будет достаточно просто.

  Ответить  
 
 автор: dirol   (02.03.2011 в 12:39)   письмо автору
 
   для: cheops   (01.03.2011 в 17:57)
 

создал вторую таблицу


CREATE TABLE IF NOT EXISTS `tags` (
  `id` int(11) NOT NULL auto_increment,
  `cid` int(11) default '0',
  `tags` varchar(300) NOT NULL,
  PRIMARY KEY  (`id`),
  KEY `catid` (`cid`)
) ENGINE=MyISAM  DEFAULT CHARSET=cp1251 AUTO_INCREMENT=122 ;

--
-- Дамп данных таблицы `tags`
--

INSERT INTO `tags` (`id`, `cid`, `tags`) VALUES
(91, 51, 'россия'),
(101, 51, 'сша'),
(111, 0, 'сша'),
(121, 51, 'италия');


где cid это номер новости в которой добавлено ключевое слово, как я понял каждое слово записывается отдельно базу? с номером конкретной новости?

сделал вывод ключевых слов с номерами новостей


 $result2 = mysql_query("SELECT DISTINCT id, cid FROM tags WHERE tags IN ('сша', 'россия', 'италия')", $sql2);
 while (list($id, $cid) = mysql_fetch_array($result2)) {
  echo"    $id, $cid<br />\n";

  }


не понял как сделать запрос чтобы были обязательно примеру 2 или 3 слова совпадающие? а не одно как щас.

  Ответить  
 
 автор: cheops   (02.03.2011 в 12:53)   письмо автору
 
   для: dirol   (02.03.2011 в 12:39)
 

Можно поступить так
SELECT * FROM news
WHERE id_news IN (SELECT DISTINCT cid FROM `tags` WHERE tags = 'россия') AND
      id_news IN (SELECT DISTINCT cid FROM `tags` WHERE tags = 'сша')

  Ответить  
 
 автор: dirol   (02.03.2011 в 13:08)   письмо автору
 
   для: cheops   (02.03.2011 в 12:53)
 

так сделал


$result3 = mysql_query("SELECT id, cid, title 
FROM news 
WHERE id IN (SELECT DISTINCT cid 
FROM `tags` 
WHERE tags = 'россия') AND
id IN (SELECT DISTINCT cid 
FROM `tags` 
WHERE tags = 'сша')", $sql2);
     while (list($id, $cid, $title) = mysql_fetch_array($result3)) {
         echo "$id, $cid, $title<br />\n";
     }


выводит из базу новость в которой есть эти два ключевых слова.
так получается все таки слова по отдельности в базе данных должны быть?

запрос делать

$dkwords="япония, россия, италия";
$mass2 = explode (",", $dkwords);


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

  Ответить  
 
 автор: cheops   (02.03.2011 в 13:45)   письмо автору
 
   для: dirol   (02.03.2011 в 13:08)
 

Да, при такой организации базы данных придется действовать так (собственно, если еще больше нормализовать таблицы - запрос еще сложнее получится). Впрочем, вы же все-равно запрос будете динамически формировать - т.е. получив массив $mass, вы на его основании будете формировать верхний запрос в цикле или при помощи implode().

  Ответить  
 
 автор: dirol   (02.03.2011 в 13:46)   письмо автору
 
   для: cheops   (02.03.2011 в 13:45)
 



      $dkwords="россия, сша, италия";
      $mass2 = explode (",", $dkwords);

       if(count($mass2)==2){
        $order="WHERE id IN (SELECT DISTINCT cid FROM `tags` WHERE tags = '".$mass2[0]."') AND id IN (SELECT DISTINCT cid FROM `tags` WHERE tags = '".$mass2[1]."')";
      }elseif(count($mass2)==3){
       $order="WHERE id IN (SELECT DISTINCT cid FROM `tags` WHERE tags = '".$mass2[0]."') AND id IN (SELECT DISTINCT cid FROM `tags` WHERE tags = '".$mass2[1]."') OR id IN (SELECT DISTINCT cid FROM `tags` WHERE tags = '".$mass2[2]."')";
      }

     $result3 = mysql_query("SELECT id, cid, title FROM news $order", $sql2);
     while (list($id, $cid, $title) = mysql_fetch_array($result3)) {
         echo "$id, $cid, $title<br />\n";
     }



так правильно? или кривовато?

  Ответить  
 
 автор: cheops   (02.03.2011 в 13:51)   письмо автору
 
   для: dirol   (02.03.2011 в 13:46)
 

Хм... может лучше фрагменты
id IN (SELECT DISTINCT cid FROM `tags` WHERE tags = '".$mass2[1]."')"

поместить в отдельный массив, который потом объединять в единый запрос при помощи implode()?
"SELECT id, cid, title FROM news WHERE ".implode(" AND ", $order)

В этом случае вы бы не зависили бы от количества ключевых слов.

  Ответить  
 
 автор: dirol   (02.03.2011 в 13:59)   письмо автору
 
   для: cheops   (02.03.2011 в 13:51)
 

извините пожалуйста, а полностью запрос не покажите как составить? простите конечно за наглость


     $result3 = mysql_query("SELECT id, cid, title FROM news WHERE ".implode(" AND ", $order), $sql2);
     while (list($id, $cid, $title) = mysql_fetch_array($result3)) {
         echo "$id, $cid, $title<br />\n";
     }


сам order как выгдядит?

  Ответить  
 
 автор: cheops   (02.03.2011 в 14:16)   письмо автору
 
   для: dirol   (02.03.2011 в 13:59)
 

Можно сформировать его как-то так
<?php
  $dkwords
="япония, россия, италия"
  
$mass2 explode (","$dkwords);
  
$order = array();
  if(!empty(
$mass2))
  {
     for(
$i 0$i count($mass2); $i++)
     {
        
$order[] = "id IN (SELECT DISTINCT cid FROM `tags` WHERE tags = '".$mass2[$i]."')"
     
}
  }
  if(!empty(
$order))
  {
     
$query "SELECT id, cid, title FROM news WHERE ".implode(" AND "$order);
     
$result3 mysql_query($query$sql2); 
     if(!
$result3) exit("Ошибка - ".mysql_error());
     while (list(
$id$cid$title) = mysql_fetch_array($result3)) { 
         echo 
"$id$cid$title<br />\n"
     }
  }
?>

  Ответить  
 
 автор: dirol   (02.03.2011 в 14:36)   письмо автору
 
   для: cheops   (02.03.2011 в 14:16)
 


    $sql2 = mysql_connect('localhost','en_islamnews','Fa6ue1hi');
    mysql_query("SET NAMES cp1251");
    mysql_select_db('en_islamnews', $sql2);



  $dkwords="сша,италия,сша";
  $mass2 = explode (",", $dkwords);
  $order = array();
  if(!empty($mass2)){
     for($i = 0; $i < count($mass2); $i++){
        $order[] = "id IN (SELECT DISTINCT cid FROM tags WHERE tags = '".$mass2[$i]."')";
     }
  }

  if(!empty($order)){
     $query = "SELECT id, cid, title FROM news WHERE ".implode(" AND ", $order);
     $result3 = mysql_query($query, $sql2);
     if(!$result3) exit("Ошибка - ".mysql_error());
     while (list($id, $cid, $title) = mysql_fetch_array($result3)) {
         echo "$id, $cid, $title<br />\n";
     }
  }


вот так то все работает, но снова проблемма возникла, он выводит теперь в том случае если есть три ключевых слова у новости.

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

а если человек в новости напишет 4-5 ключевиков то скрипт будет искать только по 5. а не хотябы 2 похожих слова

  Ответить  
 
 автор: cheops   (02.03.2011 в 14:50)   письмо автору
 
   для: dirol   (02.03.2011 в 14:36)
 

>два (россия,сша)
И правильно делает, так как у вас в требованиях "италия", или вам нужно выводить новости если есть хоть одно ключевое слово? Если так, то замените AND на OR.

  Ответить  
 
 автор: dirol   (02.03.2011 в 14:57)   письмо автору
 
   для: cheops   (02.03.2011 в 14:50)
 

нет мне надо минимум 2 или три слова, это в дальнейшем решится. щас пока на примере два слова.

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

а потом зашел и наисал еще новость но добавил три слова (сша,россия,италия) и скрипт не будет выводить те две новости где есть сша, россия а будет искать имено где есть все три слова сша,россия,италия.

вот как тут решить эту задачку?

ps ( не правельно написал
$dkwords="сша,италия,сша";
надо было
$dkwords="сша,италия,россия";)

  Ответить  
 
 автор: cheops   (02.03.2011 в 15:29)   письмо автору
 
   для: dirol   (02.03.2011 в 14:57)
 

Хм... тогда оставляйте все как есть, только извлекайте ключевые слова для новости из таблицы tags. Зачем вам вообще строка $dkwords - у вас же есть уже готовые ключевые слова в отдельной таблице?

  Ответить  
 
 автор: dirol   (02.03.2011 в 15:57)   письмо автору
 
   для: cheops   (02.03.2011 в 15:29)
 

ну тогда получается вот так как пример.


  $id=intval($_GET['id']); // ID Новости передается гетом
  $id=51; // времмено присвоим номер
  // Получам масив тегов новости
  $result = mysql_query("SELECT id, cid, tags FROM tags WHERE cid ='$id'", $sql2);
  while (list($id, $cid, $tags) = mysql_fetch_array($result)) {
    $mass2[]=$tags;;
  }

// к примеру вышли теги ( россия, сша, япония) 



как по таблице tags пробежать и найти номера новостей у которых хотя бы бы два слова совпадают?

  Ответить  
 
 автор: cheops   (02.03.2011 в 16:02)   письмо автору
 
   для: dirol   (02.03.2011 в 15:57)
 

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

  Ответить  
 
 автор: dirol   (02.03.2011 в 16:05)   письмо автору
 
   для: cheops   (02.03.2011 в 16:02)
 



--
-- Структура таблицы `news`
--

CREATE TABLE IF NOT EXISTS `news` (
  `id` int(11) NOT NULL auto_increment,
  `cid` int(11) default '0',
  `title` varchar(299) default NULL,
  `time` datetime default NULL,
  `hometext` text,
  `status` int(1) NOT NULL default '0',
  `keywords` varchar(300) NOT NULL,
  PRIMARY KEY  (`id`),
  KEY `catid` (`cid`)
) ENGINE=MyISAM  DEFAULT CHARSET=cp1251 AUTO_INCREMENT=82 ;

--
-- Дамп данных таблицы `news`
--

INSERT INTO `news` (`id`, `cid`, `title`, `time`, `hometext`, `status`, `keywords`) VALUES
(31, 0, 'заголовок 1', '2011-03-01 17:29:26', NULL, 0, 'сша, россия, италия'),
(41, 0, 'заголовок 2', '2011-03-01 17:29:26', NULL, 0, 'сша, россия, италия'),
(51, 0, 'заголовок 3', '2011-03-01 17:29:26', NULL, 0, 'россия, сша, италия'),
(61, 0, 'заголовок 4', '2011-03-01 17:29:26', NULL, 0, 'италия, россия, сша'),
(71, 0, 'пппппппппппппппппппппппп', '2011-03-01 17:36:51', 'ппппппппппппппппп', 0, 'россия, япония, курилы, италия'),
(81, 0, 'аааааааааааааа', NULL, NULL, 0, 'россия, курилы, япония');

--
-- Структура таблицы `tags`
--

CREATE TABLE IF NOT EXISTS `tags` (
  `id` int(11) NOT NULL auto_increment,
  `cid` int(11) default '0',
  `tags` varchar(300) NOT NULL,
  PRIMARY KEY  (`id`),
  KEY `catid` (`cid`)
) ENGINE=MyISAM  DEFAULT CHARSET=cp1251 AUTO_INCREMENT=192 ;

--
-- Дамп данных таблицы `tags`
--

INSERT INTO `tags` (`id`, `cid`, `tags`) VALUES
(91, 51, 'россия'),
(101, 51, 'сша'),
(111, 21, 'сша'),
(121, 51, 'япония'),
(131, 21, 'россия'),
(141, 71, 'италия'),
(151, 71, 'сша'),
(161, 71, 'россия'),
(171, 41, 'сша'),
(181, 41, 'италия'),
(191, 41, 'россия');



посмотрите пожалуйста

  Ответить  
 
 автор: cheops   (02.03.2011 в 16:15)   письмо автору
 
   для: dirol   (02.03.2011 в 16:05)
 

Хм... если привязка именно к двум ключевым словам, тогда придется формировать достаточно сложные запросы вида
SELECT * FROM news 
WHERE (id IN (SELECT DISTINCT cid FROM `tags` WHERE tags = 'россия') AND 
      id IN (SELECT DISTINCT cid FROM `tags` WHERE tags = 'италия')) OR
      (id IN (SELECT DISTINCT cid FROM `tags` WHERE tags = 'россия') AND 
      id IN (SELECT DISTINCT cid FROM `tags` WHERE tags = 'сша')) OR
      (id IN (SELECT DISTINCT cid FROM `tags` WHERE tags = 'италия') AND 
      id IN (SELECT DISTINCT cid FROM `tags` WHERE tags = 'сша'))

Формируя комбинируя пары ключевых слов из списка. Возможно стоит ограничить поиск первыми тремя ключевыми словами, так как уже в таком виде ничего хорошего в плане производительности не свети. Поиск мы ведем по строке, а не по числу - это достаточно плохо, если поле tags не будет проиндексировано. Возможно стоит подумать о том, чтобы выделить ключевые слова в отдельную таблицу, а вместо столбца tag в таблице tags оставить ключ-ссылку на эту третью таблицу.

  Ответить  
 
 автор: dirol   (02.03.2011 в 16:37)   письмо автору
 
   для: cheops   (02.03.2011 в 16:15)
 

жесть получается а не запрос.

у меня в таблице tags есть номера новостей ( cid ) может быть проще както по ней бегать и выводить номера новостей в которых есть похожие ключевые слова? а не по таблице news

  Ответить  
 
 автор: cheops   (02.03.2011 в 16:59)   письмо автору
 
   для: dirol   (02.03.2011 в 16:37)
 

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

  Ответить  
 
 автор: dirol   (02.03.2011 в 17:35)   письмо автору
 
   для: cheops   (02.03.2011 в 16:59)
 

вот от друпала код


$tag = 'новость'; // Настраиваем нужный тег. Если нужен вывод материалов по нескольким терминам, то вместо этого кода пишем следующий:
//$tags = "'термин1','термин2','термин3'";

$count = 5; // Максимальное количество выводимых нод.


$result = db_query_range(db_rewrite_sql("SELECT n.nid, n.title
FROM {node} n
INNER JOIN {term_node} tn ON n.nid = tn.nid
INNER JOIN {term_data} td ON tn.tid = td.tid
WHERE td.name = '%s' AND
n.status = 1
ORDER BY n.created DESC"),$tag,0,$count);

while ($node = db_fetch_object($result)) {
  $items[] = l($node->title, 'node/'. $node->nid);
}
$output = theme('item_list', $items);
print $output;

http://www.drupalka.ru/node/31


его можно под мои условия передать?

  Ответить  
 
 автор: cheops   (02.03.2011 в 17:40)   письмо автору
 
   для: dirol   (02.03.2011 в 17:35)
 

У них, кстати, видите 3 таблицы, а не 2 как у нас (у вас эта CMS под рукой, посмотрите, что это за таблицы и как они устроены).

  Ответить  
 
 автор: dirol   (03.03.2011 в 11:33)   письмо автору
 
   для: cheops   (02.03.2011 в 17:40)
 

в нем тупо все сделано, третья таблица соединяется с текстом. так что рабочих получается две таблицы. в одной новость, во второй ключевые слова.

  Ответить  
 
 автор: cheops   (03.03.2011 в 11:39)   письмо автору
 
   для: dirol   (03.03.2011 в 11:33)
 

Это не совсем глупо - это как раз более нормализированный вариант - вы получаете возможность искать не по тексту, а по цифрам, а это всегда быстрее, учитывая, какое количество поисковых подзапросов набегает.

  Ответить  
 
 автор: dirol   (03.03.2011 в 11:45)   письмо автору
 
   для: cheops   (03.03.2011 в 11:39)
 

все равно не понимаю. извините конечно.

а вот запрос в dle

$db->query( "SELECT id, title, date, category, alt_name, flag
FROM " . PREFIX . "_post 
WHERE MATCH (title, short_story, full_story, xfields) 
AGAINST ('$body') AND id != " . $row['id'] . " AND approve='1'" . $where_date . " 
LIMIT " . $config['related_number'] );

может на его примере сделать поиск по ключевым словам? что скажите?

  Ответить  
 
 автор: cheops   (03.03.2011 в 11:47)   письмо автору
 
   для: dirol   (03.03.2011 в 11:45)
 

А это полнотекстовый поиск - он вообще не заготовляет ключевые слова, поиск ведется прямо по тексту, индексированному индексом FULLTEXT.

Т.е. вы тоже можете текст новостей проиндексировать и искать наиболее релевантные ссылки при помощи механизма полнотекстового поиска.

  Ответить  
 
 автор: cheops   (03.03.2011 в 11:51)   письмо автору
 
   для: dirol   (03.03.2011 в 11:45)
 

Только вам придется скорее всего использовать логический режим, чтобы жестко задать вхождение ключевых слов при помощи суффикса +. Т.е. что-то вроде
SELECT * FROM news
WHERE MATCH (title,hometext) AGAINST ('+россия +сша' IN BOOLEAN MODE)

PS По полям title,hometext, конечно, нужно создать полнотекстовый индекс, иначе поиск производиться не будет. Можно, кстати, искать не по всему тексту, а по ключевым словам, раз уж они у вас все-равно есть. Тогда потребуется создать отдельный индекс по нему и прописать название keyword вместо title,hometext. Да, полнотекстовый индекс работает только с полями семейства TEXT и только в MyISAM-таблицах.

  Ответить  
 
 автор: dirol   (03.03.2011 в 12:27)   письмо автору
 
   для: cheops   (03.03.2011 в 11:51)
 

так а если сделать как раньше говорили три таблицы?

первая в ней новости

-- 
-- Структура таблицы `news` 
-- 

CREATE TABLE IF NOT EXISTS `news` ( 
  `id` int(11) NOT NULL auto_increment, 
  `cid` int(11) default '0', 
  `title` varchar(299) default NULL, 
  `time` datetime default NULL, 
  `hometext` text, 
  `status` int(1) NOT NULL default '0', 
  `keywords` varchar(300) NOT NULL, 
  PRIMARY KEY  (`id`), 
  KEY `catid` (`cid`) 
) ENGINE=MyISAM  DEFAULT CHARSET=cp1251 AUTO_INCREMENT=82 ; 

-- 
-- Дамп данных таблицы `news` 
-- 

INSERT INTO `news` (`id`, `cid`, `title`, `time`, `hometext`, `status`, `keywords`) VALUES 
(31, 0, 'заголовок 1', '2011-03-01 17:29:26', NULL, 0, 'сша, россия, италия'), 
(41, 0, 'заголовок 2', '2011-03-01 17:29:26', NULL, 0, 'сша, россия, италия'), 
(51, 0, 'заголовок 3', '2011-03-01 17:29:26', NULL, 0, 'россия, сша, италия'), 
(61, 0, 'заголовок 4', '2011-03-01 17:29:26', NULL, 0, 'италия, россия, сша'), 
(71, 0, 'пппппппппппппппппппппппп', '2011-03-01 17:36:51', 'ппппппппппппппппп', 0, 'россия, япония, курилы, италия'), 
(81, 0, 'аааааааааааааа', NULL, NULL, 0, 'россия, курилы, япония');


вторая это сами теги и номера новостей

-- 
-- Структура таблицы `tags` 
-- 

CREATE TABLE IF NOT EXISTS `tags` ( 
  `id` int(11) NOT NULL auto_increment, 
  `cid` int(11) default '0', 
  `tags` varchar(300) NOT NULL, 
  PRIMARY KEY  (`id`), 
  KEY `catid` (`cid`) 
) ENGINE=MyISAM  DEFAULT CHARSET=cp1251 AUTO_INCREMENT=192 ; 

-- 
-- Дамп данных таблицы `tags` 
-- 

INSERT INTO `tags` (`id`, `cid`, `tags`) VALUES 
(91, 51, 'россия'), 
(101, 51, 'сша'), 
(111, 21, 'сша'), 
(121, 51, 'япония'), 
(131, 21, 'россия'), 
(141, 71, 'италия'), 
(151, 71, 'сша'), 
(161, 71, 'россия'), 
(171, 41, 'сша'), 
(181, 41, 'италия'), 
(191, 41, 'россия');


и третья получается в ней id тегов и id новостей так получается?


CREATE TABLE IF NOT EXISTS `tag_id` ( 
  `id` int(11) NOT NULL auto_increment, 
  `cid` int(11) default '0', 
  `tags` int(11) default '0',
  PRIMARY KEY  (`id`), 
  KEY `catid` (`cid`) 
) ENGINE=MyISAM  DEFAULT CHARSET=cp1251; 

-- 
-- Дамп данных таблицы `tag_id` 
-- 

INSERT INTO `tag_id` (`id`, `cid`, `tags`) VALUES 
(1, 51, 91), 
(2, 51, 101), 
(3, 21, 111), 
(4, 51, 121), 
(5, 21, 131), 
(6, 71, 141), 
(7, 71, 151), 
(8, 71, 161), 
(9, 41, 171), 
(10, 41, 181), 
(11, 41, 191);


как теперь все выводить?

  Ответить  
 
 автор: dirol   (03.03.2011 в 15:52)   письмо автору
 
   для: dirol   (03.03.2011 в 12:27)
 

незнаю по уму или через иное место, во общем сделал так


$id=intval($_GET['id']); // ID Новости передается гетом
  $ids=71; // времмено присвоим номер
  $result = mysql_query("SELECT id, cid, tags FROM tags WHERE cid ='$ids'", $sql2);
  while (list($id, $cid, $tags) = mysql_fetch_array($result)) {
    $mass2[]=$tags;;
  }

  $order = array();
  if(!empty($mass2)){
     for($i = 0; $i < count($mass2); $i++){

        if (count($mass2)==2){
            $incl = "AND";
        } else {
            $incl = "OR";
        }

       $order[] = "id IN (SELECT DISTINCT cid FROM `tags` WHERE tags = '".$mass2[$i]."')";


     }
  }

  if(!empty($order)){
     $query = "SELECT id, cid, title FROM news WHERE id!='$ids' AND ".implode(" $incl ", $order);
     $result3 = mysql_query($query, $sql2);
     if(!$result3) exit("Ошибка - ".mysql_error());
     while (list($id, $cid, $title) = mysql_fetch_array($result3)) {
         echo "$id, $cid, $title<br />\n";
     }
  }

вроде работает так как задумывалось.

  Ответить  
 
 автор: dirol   (04.03.2011 в 12:36)   письмо автору
 
   для: dirol   (03.03.2011 в 15:52)
 

может кому пригодится

      $result = mysql_query("SELECT cid FROM tags WHERE tags IN (SELECT tags FROM tags WHERE cid=51) AND cid != 51 GROUP BY cid having count(*) >= 2", $sql2);
       while (list($cid) = mysql_fetch_array($result)) {
        echo "$cid<br />\n";

       }

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования