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,414 Отправлено: 3,359 |
Народ, ну я в шоке опять![]()
Только эту тему увидел...![]()
SerV всё прекрасно расписал.![]()
Добавлю лишь, что в поисковой базе сейчас около 25.000.000 записей.
МИЛЛИОНОВ!![]()
Представляете, когда человек начинает искать, а когда 10, 20,30.. 50... Одновременно![]()
Шухер полный, MySQL завешивается напрочь за полчаса.![]()
В настоящий момент поиск через поисковики, абсолютно не грузит базу, и ПРЕКРАСНО НАХОДИТ ВСЁ, причем даже удаленные темы.![]()
Правильно составляйте поисковый запрос.![]()
Трабла в том, что данный, бесплатный движок форума, просто не рассчитан на такие нагрузки![]()
Сейчас пытаемся оптимизировать и вернуть "старый" поиск.
Хотя по мне новый в разы веселее и лучше ищет![]()
![]()
Да, и кнопку "Найти" сделали, для тех кому на что нибудь нажимать надо![]()
Mercedes Benz C200 CGI BlueEFFICIENCY W204 чОрный, чОрный - был
В личке НЕ КОНСУЛЬТИРУЮ!
Спасибо: |
Получено: 7,374 Отправлено: 9,303 |
Сообщение от 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 не успевает, слишком много запросовони еще не состарились но их уже много.