0
          
          	
         
           
            
               
            
                        
            
                
                   
                  
            
            
            
					
  
   
                  
            
            
            
					
 
			
			
			
			 
			
				| Спасибо: | 
| Получено: 15 Отправлено: 0 | 
 
                  
            
            
            
					 
 
				угу. поддерживаю. + еще неск. вариантов.Сообщение от autopilot
При почти миллионе сообщений и отсутствии полнотекстового поиска странно, что до сих пор старый поиск продержался. Давно переписать этот тормоз надо было. Заменить LIKE на MATCH, переписать условия поиска и поменять индексы на FULLTEXT не так сложно.дело не в этом поиске, а в штатном, он очень вешает сервер. ну очень.
forum/includes/functions_search.php
[code]
class fulltext_search
{
function split_search_words(&$text)
{
global $user, $phpbb_root_path;
// This is where I specified the min and max for words to be added to the wordsearch table.
// You can actually make these entries in the board_config table and make $board_config global
$config = array('min_search_chars' => 3, 'max_search_chars' => 15);
static $drop_char_match, $drop_char_replace, $stopwords, $synonyms;
if (empty($drop_char_match))
{
$drop_char_match = array('^', '$', '&', '(', ')', '<_>split_search_words($message);
$split_title = ($subject) ? $this->split_search_words($subject) : array();
// Catalog first 80 words only. Feel free to change 80 to a larger value if you want to index more words
if (sizeof($split_text) > 80) {
$split_text = array_splice($split_text,0,80);
}
$words = array();
if ($mode == 'edit' || $mode == 'editpost')
{
$sql = 'SELECT w.word_id, w.word_text, m.title_match
FROM ' . SEARCH_WORD_TABLE . ' w, ' . SEARCH_MATCH_TABLE . " m
WHERE m.post_id = $post_id
AND w.word_id = m.word_id";
$result = $db->sql_query($sql);
$cur_words = array();
while ($row = $db->sql_fetchrow($result))
{
$which = ($row['title_match']) ? 'title' : 'post';
$cur_words[$which][$row['word_text']] = $row['word_id'];
}
$db->sql_freeresult($result);
if ( count($cur_words) ) {
$words['add']['post'] = array_diff($split_text, array_keys($cur_words['post']));
$words['add']['title'] = array_diff($split_title, array_keys($cur_words['title']));
$words['del']['post'] = array_diff(array_keys($cur_words['post']), $split_text);
$words['del']['title'] = array_diff(array_keys($cur_words['title']), $split_title);
} else {
$words['add']['post'] = $split_text;
$words['add']['title'] = $split_title;
$words['del']['post'] = array();
$words['del']['title'] = array();
}
}
else
{
$words['add']['post'] = $split_text;
$words['add']['title'] = $split_title;
$words['del']['post'] = array();
$words['del']['title'] = array();
}
unset($split_text);
unset($split_title);
// Get unique words from the above arrays
$unique_add_words = array_unique(array_merge($words['add']['post'], $words['add']['title']));
// We now have unique arrays of all words to be added and removed and
// individual arrays of added and removed words for text and title. What
// we need to do now is add the new words (if they don't already exist)
// and then add (or remove) matches between the words and this post
if (sizeof($unique_add_words) >= 20)
{
foreach ($unique_add_words as $pickword) {
if (! preg_match('/[0-9]/',$pickword) ) {
if (! (substr_count($pickword,substr($pickword,0,1)) > 4 || substr_count($pickword,substr($pickword,1,1)) > 4)) $new_unique_add_words[] = $pickword;
}
}
if (sizeof($new_unique_add_words)) {
$unique_add_words = $new_unique_add_words;
}
$sql = 'SELECT word_id, word_text FROM ' . SEARCH_WORD_TABLE . ' WHERE word_text IN (' . implode(', ', preg_replace('#^(.*)$#', '\'\1\'', $unique_add_words)) . ")";
$result = $db->sql_query($sql);
$word_ids = array();
while ($row = $db->sql_fetchrow($result))
{
$word_ids[$row['word_text']] = $row['word_id'];
}
$db->sql_freeresult($result);
$new_words = array_diff($unique_add_words, array_keys($word_ids));
unset($unique_add_words);
if (sizeof($new_words))
{
switch (SQL_LAYER)
{
case 'mysql':
case 'mysql4':
$sql = 'INSERT INTO ' . SEARCH_WORD_TABLE . " (word_text, post_id) VALUES ('" . implode("',$post_id),('", $new_words ) ."',$post_id)";
$db->sql_query($sql);
break;
case 'mssql':
case 'sqlite':
$sql = 'INSERT INTO ' . SEARCH_WORD_TABLE . ' (word_text) ' . implode(' UNION ALL ', preg_replace('#^(.*)$#', "SELECT '\\1'", $new_words));
$db->sql_query($sql);
break;
default:
foreach ($new_words as $word)
{
$sql = 'INSERT INTO ' . SEARCH_WORD_TABLE . " (word_text) VALUES ('$word')";
$db->sql_query($sql);
}
break;
}
}
unset($new_words);
if (sizeof($word_ids) && $post_id) {
$sql_text = implode(",",$word_ids);
$sql = " UPDATE " . SEARCH_WORD_TABLE . " SET word_common = word_common + 1 , post_id = " . $post_id . " WHERE word_id IN (" . $sql_text . ")";
$db->sql_query($sql);
}
}
foreach ($words['del'] as $word_in => $word_ary)
{
$title_match = ($word_in == 'title') ? 1 : 0;
if (sizeof($word_ary))
{
$sql_in = array();
foreach ($word_ary as $word)
{
$sql_in[] = $cur_words[$word_in][$word];
}
$sql = 'DELETE FROM ' . SEARCH_MATCH_TABLE . '
WHERE word_id IN (' . implode(', ', $sql_in) . ')
AND post_id = ' . intval($post_id) . "
AND title_match = $title_match";
$db->sql_query($sql);
unset($sql_in);
}
}
foreach ($words['add'] as $word_in => $word_ary)
{
$title_match = ($word_in == 'title') ? 1 : 0;
if (sizeof($word_ary))
{
$sql = 'INSERT INTO ' . SEARCH_MATCH_TABLE . " (post_id, word_id, title_match)
SELECT $post_id, word_id, $title_match
FROM " . SEARCH_WORD_TABLE . '
WHERE word_text IN (' . implode(', ', preg_replace('#^(.*)$#', '\'\1\'', $word_ary)) . ')';
$db->sql_query($sql);
}
}
unset($words);
return true;
}
}
[/code]
 
			
			
			
			 
			
				| Спасибо: | 
| Получено: 146 Отправлено: 16 | 
 
                  
            
            
            
					 
 
				SerV
Это твое или в phpBB полнотекстовый поиск все таки есть ?
Просто видел коды от v2.0.23 там полнотекстового нет.
 
			
			
			
			
			
				 
			
			 
			
				| Спасибо: | 
| Получено: 8,416 Отправлено: 3,359 | 
 
                  
            
            
            
					 
 
				Народ, ну я в шоке опять
Только эту тему увидел...
SerV всё прекрасно расписал.
Добавлю лишь, что в поисковой базе сейчас около 25.000.000 записей.
МИЛЛИОНОВ!
Представляете, когда человек начинает искать, а когда 10, 20,30.. 50... Одновременно
Шухер полный, MySQL завешивается напрочь за полчаса.
В настоящий момент поиск через поисковики, абсолютно не грузит базу, и ПРЕКРАСНО НАХОДИТ ВСЁ, причем даже удаленные темы.
Правильно составляйте поисковый запрос.
Трабла в том, что данный, бесплатный движок форума, просто не рассчитан на такие нагрузки
Сейчас пытаемся оптимизировать и вернуть "старый" поиск.
Хотя по мне новый в разы веселее и лучше ищет

Да, и кнопку "Найти" сделали, для тех кому на что нибудь нажимать надо
Mercedes Benz C200 CGI BlueEFFICIENCY W204 чОрный, чОрный - был
В личке НЕ КОНСУЛЬТИРУЮ!
 
			
			
			
			
			
				 
			
			 
			
				| Спасибо: | 
| Получено: 7,421 Отправлено: 9,390 | 
 
                  
            
            
            
					 
 
				Сообщение от Axl
"Найти" сделали, для тех кому на что нибудь нажимать надо

Если вам во мне что-то не нравится — не обязательно ставить меня об этом в известность. Постарайтесь пережить этот шок самостоятельно!
 
			
			
			
			 
			
				| Спасибо: | 
| Получено: 15 Отправлено: 0 | 
 
                  
            
            
            
					 
 
				прав - нет в коде. это не мое, я позаимствовал с http://www.phpbb-seo.com/ + несколько собственных домыслов.Сообщение от autopilot
SerV
Это твое или в phpBB полнотекстовый поиск все таки есть ?
Просто видел коды от v2.0.23 там полнотекстового нет.
это один из кусков кода, их (вариантов исправления) уже с 10.
как Директор решиться, думаю будем пробовать
 
			
			
			
			 
			
				| Спасибо: | 
| Получено: 146 Отправлено: 16 | 
 
                  
            
            
            
					 
 
				SerV
Если честно, я не недопонял смысла этой части кода и какое отношение это имеет к полнотекстовому поиску.
Зачем собирать в базе уникальные поисковые слова ? Возможно это как то на форуме используется... Всей картины не видно.
Я к сожалению с IPB всегда работал, в phpBB совсем не шарю.Поставил себе на локалку для самообразования.

Удачи в оптимизации форума.
 
			
			
			
			 
			
				| Спасибо: | 
| Получено: 15 Отправлено: 0 | 
 
                  
            
            
            
					 
 
				я вобщем бб тоже не фанат, даже далеко не фанатСообщение от autopilot
SerV
Если честно, я не недопонял смысла этой части кода и какое отношение это имеет к полнотекстовому поиску.
Зачем собирать в базе уникальные поисковые слова ? Возможно это как то на форуме используется... Всей картины не видно.
Я к сожалению с IPB всегда работал, в phpBB совсем не шарю.Поставил себе на локалку для самообразования.

Удачи в оптимизации форума.
вобла - рулеззз.
в куске кода я имел ввиду, что в оригинале поисковой функции даже нет обращение фултекста.
или ты предлагаешь просто phpmyadmin'ом поправить индексы?
 
			
			
			
			 
			
				| Спасибо: | 
| Получено: 1 Отправлено: 0 | 
 
                  
            
            
            
					 
 
				мда мне поиск тож не понравился, хотя раньше частенько юзал старый поиск
 
			
			
			
			 
			
				| Спасибо: | 
| Получено: 146 Отправлено: 16 | 
 
                  
            
            
            
					 
 
				SerV
Так это одно из обязательных условий (кстати в зависимости от сервера это может занять несколько часов). А так же переписать LIKE на MATCH AGAINST и переписать условия поиска (в MATCH AGAINST не используются выражения AND и OR как в LIKE). В основном это нужно сделать в запросах с выборкой из таблицы phpbb_post_text.или ты предлагаешь просто phpmyadmin'ом поправить индексы?
Собственно можно посмотреть как в той же вобле все реализовано и переделать под phpBB.
Добавлено спустя 1 минуту 45 секунд:
Да... И я все пишу по версии phpBB 2.0.23. В версии 3.х может по другому все.
Добавлено спустя 42 минуты 48 секунд:
посмотрел сейчас как поиск сделан на phpBB.....
помимо собственно записи поста в базу, весь пост разбивается на отдельные слова и еще раз все слова отдельно заносятся в базу.
поиск выполняется в основном насколько я понял именно по таблицам с отдельными словами. там есть условие при котором поиск выполняется по самому посту, но похоже в нашем случае это условие не работает.
В этом случае полнотекстовый поиск не реализовать.
Смысла в нем не будет. Нужно убирать условие при котором поиск производится по отдельным словам и искать по основному тексту поста (таблица phpbb_posts_text).
Вообще я первый раз такое вижу. Там еще на каждое слово свой запрос, чем больше слов в поиске тем больше запросов выполняется... По базе с офигительной кучей слов. Тихий ужас...
 
			
			
			
			 
			
				| Спасибо: | 
| Получено: 15 Отправлено: 0 | 
 
                  
            
            
            
					 
 
				тут 2.х, в 3.х уже есть фултекст
ну вобщем наверно как-то так:
[code]
открыть: search.php
найти:
for($i = 0; $i <count>sql_query($sql)))
{
message_die(GENERAL_ERROR, 'Could not obtain matched posts list', '', __LINE__, __FILE__, $sql);
}
$total_posts = 0;
while($temp_row = $db->sql_fetchrow($result))
{
$result_list[$temp_row['post_id']] = 1;
}
for($i = 0; false; $i++)
-----------------------------------------------
открыть: includes/functions_search.php
найти:
function add_search_words($mode, $post_id, $post_text, $post_title = '')
{
после этого куска - добавить:
return;
***
найти:
function remove_common($mode, $fraction, $word_id_list = array())
{
опять добавить (после "{"):
return;
***
найти:
function remove_search_post($post_id_sql)
{
и опять добавляем (после "{"):
return;
-----------------------------------------------
открыть: templates/subSilver/search_body.tpl
найти:
<td><span><input>
<input> {L_SEARCH_ANY_TERMS}
<input> {L_SEARCH_ALL_TERMS}</span></td>
заменить на:
<td><span><input>
<BEGIN>
<input> {L_SEARCH_ANY_TERMS}
<input> {L_SEARCH_ALL_TERMS}
<END>
</span></td>
***
найти:
<td><span><select>{S_TIME_OPTIONS}</select>
<input> {L_SEARCH_MESSAGE_TITLE}
<input> {L_SEARCH_MESSAGE_ONLY}</span></td>
заменить на:
<td><span><select>{S_TIME_OPTIONS}</select>
<BEGIN>
<input> {L_SEARCH_MESSAGE_TITLE}
<input> {L_SEARCH_MESSAGE_ONLY}
<END>
</span></td>
-----------------------------------------------
открыть: language/lang_english/lang_main.php
найти:
$lang['Search_keywords_explain'] = 'You can use <u>AND</u> to define words which must be in the results, <u>OR</u> to define words which may be in the result and <u>NOT</u> to define words which should not be in the result. Use * as a wildcard for partial matches';
заменить на:
$lang['Search_keywords_explain'] = 'поиск в сообщениях и заголовках тем.
примечание: поиск не чувствителен к регистру.
поисковое слово не может быть менее 4-х букв.
служебные термины игнорируются.
используйте * в качестве шаблона для частичного совпадения, пример: турби* (турбина, турбированый).
введите <span>слово1 слово2</span> чтобы найти все темы со словом1 <u>или</u> словом2
введите <span>+слово1 +слово2</span> чтобы найти все темы со словом1 <u>и</u> словом2
введите <span>+слово1 +слово2 -слово3</span> чтобы найти все темы со словом1 <u>и</u> словом2, но <u>без</u> слова3.
используйте <span>"слово1 слово2"</span> (в двойных кавычках) чтобы найти <u>точную фразу</u>.';
-----------------------------------------------
открываем phpmyadmin и выполняем запрос:
ALTER TABLE phpbb_posts_text ADD FULLTEXT (post_subject, post_text), delay_key_write = 1;
TRUNCATE phpbb_search_wordlist;
TRUNCATE phpbb_search_wordmatch;
ну и всё...
[/code]
 
			
			
			
			 
			
				| Спасибо: | 
| Получено: 146 Отправлено: 16 | 
 
                  
            
            
            
					 
 
				SerV
че-то не понятно что в search.php надо сделать... есть "найти", а чего дальше не написано, сразу "открыть: includes/functions_search.php".
Добавлено спустя 3 минуты 52 секунды:
лучше из шела...ALTER TABLE phpbb_posts_text ADD FULLTEXT (post_subject, post_text)
 
			
			
			
			 
			
				| Спасибо: | 
| Получено: 15 Отправлено: 0 | 
 
                  
            
            
            
					 
 
				форум срезал, было:
[code]
заменить на:
$max_retrieve_results = 20000;
$phrase = mysql_escape_string($search_keywords);
$phrase = str_replace('\\\"', '"', $phrase);
$sql = "select post_id from " . POSTS_TEXT_TABLE .
" where match (post_subject, post_text) against('$phrase' in boolean mode) limit $max_retrieve_results";
if ( !($result = $db->sql_query($sql)))
{
message_die(GENERAL_ERROR, 'Could not obtain matched posts list', '', __LINE__, __FILE__, $sql);
}
$total_posts = 0;
while($temp_row = $db->sql_fetchrow($result))
{
$result_list[$temp_row['post_id']] = 1;
}
for($i = 0; false; $i++)
[/code]
возможно форум что-то срезает, в "блокноте" полный
 
			
			
			
			 
			
				| Спасибо: | 
| Получено: 146 Отправлено: 16 | 
 
                  
            
            
            
					 
 
				Видимо да... Т.к. тут явно что-то напутановозможно форум что-то срезает:
Тэг "Код" видимо че-то режет...найти:
for($i = 0; $i <count>sql_query($sql)))
{
message_die(GENERAL_ERROR, 'Could not obtain matched posts list', '', __LINE__, __FILE__, $sql);
}
Когда запуск ?
 
			
			
			
			 
			
				| Спасибо: | 
| Получено: 15 Отправлено: 0 | 
 
                  
            
            
            
					 
 
				Тэг "Код" видимо че-то режет...Сообщение от autopilot
Видимо да... Т.к. тут явно что-то напутановозможно форум что-то срезает:
[quote:2bc1bg4a]найти:
for($i = 0; $i <count>sql_query($sql)))
{
message_die(GENERAL_ERROR, 'Could not obtain matched posts list', '', __LINE__, __FILE__, $sql);
}
Когда запуск ?[/quote:2bc1bg4a]
гмм, да, чёт форум дурит с резалкой
должно быть так
сейчас проверяю на тестовом аккаунте.
нуна Директора подначить на операцию
правда придется форум закрыть на неск. часов, а то с базой опасно баловаться в рабочем режиме
 
			
			
			
			 
			
				| Спасибо: | 
| Получено: 146 Отправлено: 16 | 
 
                  
            
            
            
					 
 
				20000 ?$max_retrieve_results = 20000;А не много ли постов в результатах поиска ?
Кстати можно замутить что-то вроде:
после:$phrase = preg_replace( "/\s+and\s+/i", " ", $phrase );
$phrase = preg_replace( "/\s+not\s+/i", " -", $phrase );
$phrase = preg_replace( "/\s+or\s+/i", ' ~', $phrase );
тогда OR, AND и NOT работать будут при поиске. Только нужно с OR поосторожнее....$phrase = str_replace('\\\"', '"', $phrase);
Полный бэкап перенести на локалку и играться до получения хорошего результата проверяя все режимы.правда придется форум закрыть на неск. часов, а то с базой опасно баловаться в рабочем режиме
 
			
			
			
			 
			
				| Спасибо: | 
| Получено: 15 Отправлено: 0 | 
 
                  
            
            
            
					 
 
				после:Сообщение от autopilot
20000 ?$max_retrieve_results = 20000;А не много ли постов в результатах поиска ?
Кстати можно замутить что-то вроде:
[quote:ulqdsg59]$phrase = preg_replace( "/\s+and\s+/i", " ", $phrase );
$phrase = preg_replace( "/\s+not\s+/i", " -", $phrase );
$phrase = preg_replace( "/\s+or\s+/i", ' ~', $phrase );
тогда OR, AND и NOT работать будут при поиске. Только нужно с OR поосторожнее....$phrase = str_replace('\\"', '"', $phrase);
Полный бэкап перенести на локалку и играться до получения хорошего результата проверяя все режимы.[/quote:ulqdsg59]правда придется форум закрыть на неск. часов, а то с базой опасно баловаться в рабочем режиме
я просто "шкурный" интерес хочу внедрить, чтобы научить общепринятому языку запросов
т.е. уйти от OR, AND и NOT и заменить на +-""
впринципе как показывает практика, 99% юзеров просто пишут в поиск: ремонт турбины
и не заморачиваются на сложное построение запроса.
хмм ну это я так 20 000, вобщем можно действительно "деноминировать". я еще в процессе обдумывания рабочего варианта.
 
			
			
			
			 
			
				| Спасибо: | 
| Получено: 146 Отправлено: 16 | 
 
                  
            
            
            
					 
 
				я просто "шкурный" интерес хочу внедрить, чтобы научить общепринятому языку запросов

По поиску можно редирект сделать. Еще немного разгрузит БД. После поиска (сложный запрос) идет сразу вывод результатов (еще один не простой запрос с выборкой из кучи таблиц). Можно разбить, занося результаты поиска в таблицу с временем "жизни" минут 30, юзеру страничку "подождите, сейчас вы будете перемещены к результатам поиска" с задержкой в 1-2 сек., ну и потом сами результаты.
Помоему в вобле такое есть. Но это уже за 5 минут не написать...
Я просто сомневаюсь, что больше 1000-1500 кто-то осилит листать/читать. Полнотекстовый с релевантностью работает, там все равно самые похожие посты будут в начале.хмм ну это я так 20 000, вобщем можно действительно "деноминировать".
 
			
			
			
			 
			
				| Спасибо: | 
| Получено: 15 Отправлено: 0 | 
 
                  
            
            
            
					 
 
				ну сторить еще тоже надо мудрить, я пока незнаю как это грамотно описать. моих мозгов не хватит, а вот кстати задержать пожалуй можно.Сообщение от autopilot
я просто "шкурный" интерес хочу внедрить, чтобы научить общепринятому языку запросов

По поиску можно редирект сделать. Еще немного разгрузит БД.
функцией DELAYED, если база занята, то поиск подождет
к примеру
sql = "INSERT IGNORE INTO " . SEARCH_WORD_TABLE
на
sql = "INSERT DELAYED IGNORE INTO " . SEARCH_WORD_TABLE
это 222 строка functions_search.php
Добавлено спустя 9 минут 54 секунды:
кстати перед бекапом, не почистить ли phpbb_search_results
ибо нафик? их мнооого накопилось
 
			
			
			
			 
			
				| Спасибо: | 
| Получено: 146 Отправлено: 16 | 
 
                  
            
            
            
					 
 
				Практически ничего не даст. Тем более с этими инсертами, ты их убрал уже (добавлял return в файле functions_search.php).а вот кстати задержать пожалуй можно.
функцией DELAYED, если база занята, то поиск подождет
Так все уже написано за нас.ну сторить еще тоже надо мудрить, я пока незнаю как это грамотно описать. моих мозгов не хватит
Ты же когда по страницам результатов поиска ходишь ничего заново не ищется. Посмотри строки с 675 по 760 (примерно) файла search.php результаты поиска заносятся в уже существующую таблицу и в дальнейшем используются. Именно это можно обыграть себе на пользу.
Так они вообще сами должны удаляться, автоматом. Опять же смотри строки c 675 файла search.php. Можно и в ручную конечно грохнутькстати перед бекапом, не почистить ли phpbb_search_results
ибо нафик? их мнооого накопилось
Добавлено спустя 2 минуты 49 секунд:
З.Ы.: У меня с 675 строки идет вот это:
//
// Delete old data from the search result table
//
 
			
			
			
			 
			
				| Спасибо: | 
| Получено: 15 Отправлено: 0 | 
 
                  
            
            
            
					 
 
				гмм, действительно. логичноСообщение от autopilot
Практически ничего не даст. Тем более с этими инсертами, ты их убрал уже (добавлял return в файле functions_search.php).а вот кстати задержать пожалуй можно.
функцией DELAYED, если база занята, то поиск подождет
Так все уже написано за нас.ну сторить еще тоже надо мудрить, я пока незнаю как это грамотно описать. моих мозгов не хватит
Ты же когда по страницам результатов поиска ходишь ничего заново не ищется. Посмотри строки с 675 по 760 (примерно) файла search.php результаты поиска заносятся в уже существующую таблицу и в дальнейшем используются. Именно это можно обыграть себе на пользу.[/quote]
это да, но это и так работает.
хотелось бы не переступить черту загрузки базы, отсрочить запрос если уже пошел аут.
Так они вообще сами должны удаляться, автоматом. Опять же смотри строки c 675 файла search.php. Можно и в ручную конечно грохнутькстати перед бекапом, не почистить ли phpbb_search_results
ибо нафик? их мнооого накопилось[/quote]
ну я думаю Игорь точно скажет сколько там в них, но для этого форума prune не успевает, слишком много запросовони еще не состарились но их уже много.

