olegvs Опубликовано 20 Января 2009 Жалоба Поделиться Опубликовано 20 Января 2009 С ростом журналов поиск стал сильной проблемой, особенно в комментах.Два-три поиска, запущенных одновременно убивали MySQL.Ограничивал число результатов поиска пока поиск в коментах вообще не выключил, что есть очень плохо. Озаботился полнотесктовым, вроде не нашёл упоминаний, чтобы это кто-то делал. Попробовал сам, но не уверен, что всё сделал корректно. Что сделал? /journal/misc/user_search.php1. закомментировал: $DB->query("SELECT p.pid FROM ibf_jposts p WHERE p.journal_id='".$journal->users['id']."' AND (".$search['SEARCH'].")".$q_extra." LIMIT 1000");после вставил: $DB->query("SELECT p.pid FROM ibf_jposts p WHERE MATCH (post, title) AGAINST ('".$search['SEARCH']."' IN BOOLEAN MODE) AND p.journal_id='".$journal->users['id']."' ".$q_extra." LIMIT 1000"); 2. закомментировал: $DB->query("SELECT cid FROM ibf_jcomments c LEFT JOIN ibf_jposts p ON (p.pid=c.post_id) LEFT JOIN ibf_jmembers m ON (m.id=c.owner_id) WHERE c.owner_id = '".$journal->users['id']."' AND (".$search['SEARCH'].")".$q_extra." LIMIT 1000");после вставил: $DB->query("SELECT cid FROM ibf_jcomments c LEFT JOIN ibf_jposts p ON (p.pid=c.post_id) LEFT JOIN ibf_jmembers m ON (m.id=c.owner_id) WHERE c.owner_id = '".$journal->users['id']."' AND MATCH (c.post) AGAINST ('".$search['SEARCH']."' IN BOOLEAN MODE)".$q_extra." LIMIT 1000"); 3. закомментировал: function make_search_text($q = "LCASE(p.post)") { global $ibforums; $name = strtolower(trim(urldecode($ibforums->input['name']))); $name = str_replace("&","&",$name); $name = preg_replace( "/\&\#[0-9]+;|<br \/>|\&(gt|lt|quot|amp);/i", "", $name ); $name = preg_replace( "/[^a-zA-Z0-9р- └-▀\|\&\s]/", "", $name ); $name = preg_replace( "/^(?:img|quote|code|html|javascript|a href|color|span|div|border|style|class)$/", "", $name ); // add space if not set with |,& (word&word must be word & word) $name = preg_replace("/([\&\|])(\S+?)/","\\1 \\2",$name); $name = preg_replace("/(\S+?)([\&\|])/","\\1 \\2",$name); // remove smaller word ( <4 ) $name = preg_replace("/(^|[\|\&\s]+)\S{1,3}([\|\&\s]+|$)/","\\2",$name); // remove first |,& $name = preg_replace("/^([\|\&\s]+)/","",$name); // remove last |,& $name = preg_replace("/([\|\&\s]+)$/","",$name); // remove double |,& $name = preg_replace("/(\s[\&\|]){2,}/","\\1",$name); $search_name = array('ORIGINAL' => $name, 'SEARCH' => '', 'HLITE' => array()); $name = explode(" ",$name); $next_sep = ""; foreach ($name as $val) { if ($val == "") { continue; } if ($val == '|') { $next_sep = 'OR'; } else if ($val == '&') { $next_sep = 'AND'; } else { if ($search_name['SEARCH'] != "") $search_name['SEARCH'] .= $next_sep." "; $search_name['SEARCH'] .= $q." LIKE '%".trim($val)."%' "; $next_sep = 'AND'; $search_name['HLITE'][] = trim($val); } } // remove unused :) $search_name['SEARCH'] = preg_replace("/[\|\&]/","",$search_name['SEARCH']); return $search_name; }после вставил: function make_search_text($q = "LCASE(p.post)") { global $ibforums; // force to lowercase and swop % into a safer version $words = trim( rawurldecode($ibforums->input['name']) ); $words = str_replace( '|', "|", $words ); // Remove crap $words = str_replace( """, '"', $words ); $words = str_replace( ">" , ">", $words ); $words = str_replace( "%" , "" , $words ); //----------------------------------------- // If it's a phrase in quotes.. //----------------------------------------- if ( preg_match( "#^\"(.+?)\"$#", $words ) ) { return $words; } // Remove common words.. $words = preg_replace( "/^(?:img|quote|code|html|javascript|a href|color|span|div|border|style)$/", "", $words ); // OK, lets break up the keywords // this or that and this not me $words = preg_replace( "/\s+and\s+/i", " ", $words ); // this or that this not me $words = preg_replace( "/\s+not\s+/i", " -", $words ); // this or that this -me $words = preg_replace( "/\s+or\s+/i", ' ~', $words ); // this ~that this -me # Was added as a bug fix but really this causes more problems # than it solves. Complaint was that it should default to AND # matching, not OR matching. Problem is that it doesn't then # give a "true" search as one would expect Google to do. //$words = preg_replace( "/\s+(?!-|~)/", " +", $words ); // this ~that +this -me $name = str_replace( "~", "", $words ); $search_name = array('ORIGINAL' => $name, 'SEARCH' => '+'.$name, 'HLITE' => array()); $name = explode(" ",$name); foreach ($name as $val) { if (($val == "") or ($val == '*') or ($val == '+') or ($val == '-') or ($val == '~')) { continue; } $search_name['HLITE'][] = trim($val); } return $search_name; } /journal/misc/main_search.php4. закомментировал: $DB->query("SELECT p.pid FROM ibf_jposts p LEFT JOIN ibf_jmembers m ON (m.id=p.journal_id) WHERE (".$search['SEARCH'].")".$q_extra." LIMIT 1000");после вставил: $DB->query("SELECT p.pid FROM ibf_jposts p LEFT JOIN ibf_jmembers m ON (m.id=p.journal_id) WHERE MATCH (post, title) AGAINST ('".$search['SEARCH']."' IN BOOLEAN MODE) ".$q_extra." LIMIT 1000"); 5. закомментировал: $DB->query("SELECT cid FROM ibf_jcomments c LEFT JOIN ibf_jposts p ON (p.pid=c.post_id) LEFT JOIN ibf_jmembers m ON (m.id=p.journal_id) WHERE (".$search['SEARCH'].")".$q_extra." LIMIT 1000");после вставил: $DB->query("SELECT cid FROM ibf_jcomments c LEFT JOIN ibf_jposts p ON (p.pid=c.post_id) LEFT JOIN ibf_jmembers m ON (m.id=p.journal_id) WHERE MATCH (c.post) AGAINST ('".$search['SEARCH']."' IN BOOLEAN MODE) ".$q_extra." LIMIT 1000"); 6. закомментировал: function make_search_text($q = "LCASE(p.post)") { global $ibforums; $name = strtolower(trim(urldecode($ibforums->input['name']))); $name = str_replace("&","&",$name); $name = preg_replace( "/\&\#[0-9]+;|<br \/>|\&(gt|lt|quot|amp);/i", "", $name ); $name = preg_replace( "/[^a-zA-Z0-9р- └-▀\|\&\s]/", "", $name ); $name = preg_replace( "/^(?:img|quote|code|html|javascript|a href|color|span|div|border|style|class)$/", "", $name ); // add space if not set with |,& (word&word must be word & word) $name = preg_replace("/([\&\|])(\S+?)/","\\1 \\2",$name); $name = preg_replace("/(\S+?)([\&\|])/","\\1 \\2",$name); // remove smaller word ( <4 ) $name = preg_replace("/(^|[\|\&\s]+)\S{1,3}([\|\&\s]+|$)/","\\2",$name); // remove first |,& $name = preg_replace("/^([\|\&\s]+)/","",$name); // remove last |,& $name = preg_replace("/([\|\&\s]+)$/","",$name); // remove double |,& $name = preg_replace("/(\s[\&\|]){2,}/","\\1",$name); $search_name = array('ORIGINAL' => $name, 'SEARCH' => '', 'HLITE' => array()); $name = explode(" ",$name); $next_sep = ""; foreach ($name as $val) { if ($val == "") { continue; } if ($val == '|') { $next_sep = 'OR'; } else if ($val == '&') { $next_sep = 'AND'; } else { if ($search_name['SEARCH'] != "") $search_name['SEARCH'] .= $next_sep." "; $search_name['SEARCH'] .= $q." LIKE '%".trim($val)."%' "; $next_sep = 'AND'; $search_name['HLITE'][] = trim($val); } } // remove unused :) $search_name['SEARCH'] = preg_replace("/[\|\&]/","",$search_name['SEARCH']); return $search_name; }после вставил: function make_search_text($q = "LCASE(p.post)") { global $ibforums; // force to lowercase and swop % into a safer version $words = trim( rawurldecode($ibforums->input['name']) ); $words = str_replace( '|', "|", $words ); // Remove crap $words = str_replace( """, '"', $words ); $words = str_replace( ">" , ">", $words ); $words = str_replace( "%" , "" , $words ); //----------------------------------------- // If it's a phrase in quotes.. //----------------------------------------- if ( preg_match( "#^\"(.+?)\"$#", $words ) ) { return $words; } // Remove common words.. $words = preg_replace( "/^(?:img|quote|code|html|javascript|a href|color|span|div|border|style)$/", "", $words ); // OK, lets break up the keywords // this or that and this not me $words = preg_replace( "/\s+and\s+/i", " ", $words ); // this or that this not me $words = preg_replace( "/\s+not\s+/i", " -", $words ); // this or that this -me $words = preg_replace( "/\s+or\s+/i", ' ~', $words ); // this ~that this -me # Was added as a bug fix but really this causes more problems # than it solves. Complaint was that it should default to AND # matching, not OR matching. Problem is that it doesn't then # give a "true" search as one would expect Google to do. //$words = preg_replace( "/\s+(?!-|~)/", " +", $words ); // this ~that +this -me $name = str_replace( "~", "", $words ); $search_name = array('ORIGINAL' => $name, 'SEARCH' => '+'.$name, 'HLITE' => array()); $name = explode(" ",$name); foreach ($name as $val) { if (($val == "") or ($val == '*') or ($val == '+') or ($val == '-') or ($val == '~')) { continue; } $search_name['HLITE'][] = trim($val); } return $search_name; } /cache/lang_cache/ru/lang_journal.php7. нашёл'j_s_rules_text' => "<b>Поиск по интересам, антиресам и нику пользователя</b><br />При поиске в интересах и антиресах все символы кроме букв, цифр и символов * и ? игнорируются.<br />При поиске разрешено использовать общепринятые сокращения (* и ?).<br /><br />При поиске дневника по нику можно использовать любые символы, однако символы * и ? будут восприняты как сокращения.<br /><br />Например: <b>игр*</b><br /> - найдет все слова начинающиеся на <b>игр</b> (игра, игроки, игрушки и т.д.).<br /><br />Например: <b>игр?</b><br /> - найдет слова 'игра', 'игры' и т.д., но не найдет слова 'игроки' и 'игрушки'.<br /><br />Например: <b>игр</b><br /> - найдет только слово 'игр'.<br /><br /><br /> <b>Поиск по записям и комментариям</b><br />При поиске все символы кроме букв, цифр, символов & и | , а так же слова состоящие меньше чем из 4 букв игнорируются.<br />Запрещено использовать символы сокращений (* и ?).<br /> При поиске будут найдены все слова включающие в себя заданные при поиске части слов.<br /><br />Например: <b>игра</b><br /> - найдет слова 'игра', 'поиграть', 'играют' и проч.<br /><br />При поиске допустимо указывать несколько слов и использовать логические операторы. <br />Допустимы следующие операторы:<br /> <b>&</b> - логическое И<br /> <b>|</b> - логическое ИЛИ.<br /><br /> Например: <b>игра & компьютер</b> - найдет все записи содержащие одновременно слово 'игра' и слово 'компьютер'<br /><br />Например: <b>игра | компьютер</b> - найдет все записи содержащие либо слово 'игра', либо слово 'компьютер'<br /><br />Если между словами не указан ни один из операторов, то по умолчанию используется оператор <b>&</b><br /><br /> Например: <b>игра компьютер</b> - равнозначно указанию <b>игра & компьютер</b><br /><br />",заменил на:'j_s_rules_text' => "<b>Поиск по интересам, антиресам и нику пользователя</b><br />При поиске в интересах и антиресах все символы кроме букв, цифр и символов * и ? игнорируются.<br />При поиске разрешено использовать общепринятые сокращения (* и ?).<br /><br />При поиске журнала по нику можно использовать любые символы, однако символы * и ? будут восприняты как сокращения.<br /><br />Например: <b>игр*</b><br /> - найдет все слова начинающиеся на <b>игр</b> (игра, игроки, игрушки и т.д.).<br /><br />Например: <b>игр?</b><br /> - найдет слова 'игра', 'игры' и т.д., но не найдет слова 'игроки' и 'игрушки'.<br /><br />Например: <b>игр</b><br /> - найдет только слово 'игр'.<br /><br /><br /> <b>Поиск по записям и комментариям</b><br />яблоко банан - Поиск сообщений, содержащих одно из этих слов<br /> +яблоко +сок ===> Поиск сообщений, содержащих оба этих слова<br /> +яблоко -сок ===> Поиск сообщений, содержащих слово 'яблоко' и не содержащих слова 'сок'<br /> ябло* ===> Поиск сообщений, содержащих слово 'яблоко' и/или 'яблочный'<br /> \"Некоторые слова\" ===> Поиск сообщений, содержащих фразы 'некоторые слова являются мудрыми', 'некоторые слова' и не содержащих фразу 'некоторые нецензурные слова'<br /><br />", 8. SQLALTER TABLE `ibf_jposts` ENGINE = MYISAM; ALTER TABLE `ibf_jposts` ADD FULLTEXT ( `post` , `title` ); ALTER TABLE `ibf_jcomments` ENGINE = MYISAM; ALTER TABLE `ibf_jcomments` ADD FULLTEXT ( `post` ); Тем, кто не понимает, что происходит, крайне не советую производить эти изменения.На моём форуме вроде всё работает, но....В общем тем кто разбирается просьба оценить и совместно довести до ума. Цитата Ссылка на комментарий Поделиться на других сайтах Прочее
WildRAID Опубликовано 20 Января 2009 Жалоба Поделиться Опубликовано 20 Января 2009 На первый взгляд - всё ок. P.S. Какой у вас милый форум. Цитата Ссылка на комментарий Поделиться на других сайтах Прочее
olegvs Опубликовано 23 Января 2009 Автор Жалоба Поделиться Опубликовано 23 Января 2009 На первый взгляд - всё ок. P.S. Какой у вас милый форум. спасибо Цитата Ссылка на комментарий Поделиться на других сайтах Прочее
Рекомендуемые сообщения
Присоединиться к обсуждению
Вы можете ответить сейчас, а зарегистрироваться позже. Если у вас уже есть аккаунт, войдите, чтобы ответить от своего имени.