0
-
24.02.2009, 12:31 #41
- Регистрация
- 18.04.2008
- Адрес
- Россия, Москва, ЮЗАО
- Возраст
- 45
- Сообщений
- 4,022
Спасибо: Получено: 15
Отправлено: 0
Сообщение от autopilot
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]
-
24.02.2009, 12:38 #42
- Регистрация
- 06.03.2007
- Адрес
- Россия, Москва, СЗАО
- Возраст
- 49
- Сообщений
- 2,144
- Записей в дневнике
- 1
Спасибо: Получено: 146
Отправлено: 16
0SerV
Это твое или в phpBB полнотекстовый поиск все таки есть ?
Просто видел коды от v2.0.23 там полнотекстового нет.
-
24.02.2009, 12:41 #43
- Регистрация
- 06.10.2004
- Адрес
- Россия, Сергиев Посад
- Возраст
- 50
- Сообщений
- 37,580
- Записей в дневнике
- 14
Спасибо: Получено: 8,374
Отправлено: 3,359
0Народ, ну я в шоке опять
Только эту тему увидел...
SerV всё прекрасно расписал.
Добавлю лишь, что в поисковой базе сейчас около 25.000.000 записей.
МИЛЛИОНОВ!
Представляете, когда человек начинает искать, а когда 10, 20,30.. 50... Одновременно
Шухер полный, MySQL завешивается напрочь за полчаса.
В настоящий момент поиск через поисковики, абсолютно не грузит базу, и ПРЕКРАСНО НАХОДИТ ВСЁ, причем даже удаленные темы.
Правильно составляйте поисковый запрос.
Трабла в том, что данный, бесплатный движок форума, просто не рассчитан на такие нагрузки
Сейчас пытаемся оптимизировать и вернуть "старый" поиск.
Хотя по мне новый в разы веселее и лучше ищет
Да, и кнопку "Найти" сделали, для тех кому на что нибудь нажимать надоMercedes Benz C200 CGI BlueEFFICIENCY W204 чОрный, чОрный - был
В личке НЕ КОНСУЛЬТИРУЮ!
-
24.02.2009, 12:43 #44
- Регистрация
- 11.10.2007
- Адрес
- Russian Federation, olympic city
- Возраст
- 38
- Сообщений
- 55,542
Спасибо: Получено: 6,998
Отправлено: 8,735
0Сообщение от AxlЕсли вам во мне что-то не нравится — не обязательно ставить меня об этом в известность. Постарайтесь пережить этот шок самостоятельно!
-
24.02.2009, 12:50 #45
- Регистрация
- 18.04.2008
- Адрес
- Россия, Москва, ЮЗАО
- Возраст
- 45
- Сообщений
- 4,022
Спасибо: Получено: 15
Отправлено: 0
0Сообщение от autopilot
это один из кусков кода, их (вариантов исправления) уже с 10.
как Директор решиться, думаю будем пробовать
-
24.02.2009, 13:07 #46
- Регистрация
- 06.03.2007
- Адрес
- Россия, Москва, СЗАО
- Возраст
- 49
- Сообщений
- 2,144
- Записей в дневнике
- 1
Спасибо: Получено: 146
Отправлено: 16
0SerV
Если честно, я не недопонял смысла этой части кода и какое отношение это имеет к полнотекстовому поиску.
Зачем собирать в базе уникальные поисковые слова ? Возможно это как то на форуме используется... Всей картины не видно.
Я к сожалению с IPB всегда работал, в phpBB совсем не шарю. Поставил себе на локалку для самообразования.
Удачи в оптимизации форума.
-
24.02.2009, 13:24 #47
- Регистрация
- 18.04.2008
- Адрес
- Россия, Москва, ЮЗАО
- Возраст
- 45
- Сообщений
- 4,022
Спасибо: Получено: 15
Отправлено: 0
0Сообщение от autopilot
вобла - рулеззз.
в куске кода я имел ввиду, что в оригинале поисковой функции даже нет обращение фултекста.
или ты предлагаешь просто phpmyadmin'ом поправить индексы?
-
24.02.2009, 13:24 #48
- Регистрация
- 18.09.2005
- Адрес
- Россия, Москва, СЗАО
- Возраст
- 43
- Сообщений
- 1,247
Спасибо: Получено: 1
Отправлено: 0
0мда мне поиск тож не понравился, хотя раньше частенько юзал старый поиск
-
24.02.2009, 14:25 #49
- Регистрация
- 06.03.2007
- Адрес
- Россия, Москва, СЗАО
- Возраст
- 49
- Сообщений
- 2,144
- Записей в дневнике
- 1
Спасибо: Получено: 146
Отправлено: 16
0SerV
или ты предлагаешь просто phpmyadmin'ом поправить индексы?
Собственно можно посмотреть как в той же вобле все реализовано и переделать под phpBB.
Добавлено спустя 1 минуту 45 секунд:
Да... И я все пишу по версии phpBB 2.0.23. В версии 3.х может по другому все.
Добавлено спустя 42 минуты 48 секунд:
посмотрел сейчас как поиск сделан на phpBB.....
помимо собственно записи поста в базу, весь пост разбивается на отдельные слова и еще раз все слова отдельно заносятся в базу.
поиск выполняется в основном насколько я понял именно по таблицам с отдельными словами. там есть условие при котором поиск выполняется по самому посту, но похоже в нашем случае это условие не работает.
В этом случае полнотекстовый поиск не реализовать.
Смысла в нем не будет. Нужно убирать условие при котором поиск производится по отдельным словам и искать по основному тексту поста (таблица phpbb_posts_text).
Вообще я первый раз такое вижу. Там еще на каждое слово свой запрос, чем больше слов в поиске тем больше запросов выполняется... По базе с офигительной кучей слов. Тихий ужас...
-
24.02.2009, 14:38 #50
- Регистрация
- 18.04.2008
- Адрес
- Россия, Москва, ЮЗАО
- Возраст
- 45
- Сообщений
- 4,022
Спасибо: Получено: 15
Отправлено: 0
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]
-
24.02.2009, 14:52 #51
- Регистрация
- 06.03.2007
- Адрес
- Россия, Москва, СЗАО
- Возраст
- 49
- Сообщений
- 2,144
- Записей в дневнике
- 1
Спасибо: Получено: 146
Отправлено: 16
0SerV
че-то не понятно что в search.php надо сделать... есть "найти", а чего дальше не написано, сразу "открыть: includes/functions_search.php".
Добавлено спустя 3 минуты 52 секунды:
ALTER TABLE phpbb_posts_text ADD FULLTEXT (post_subject, post_text)
-
24.02.2009, 14:58 #52
- Регистрация
- 18.04.2008
- Адрес
- Россия, Москва, ЮЗАО
- Возраст
- 45
- Сообщений
- 4,022
Спасибо: Получено: 15
Отправлено: 0
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]
возможно форум что-то срезает, в "блокноте" полный
-
24.02.2009, 15:12 #53
- Регистрация
- 06.03.2007
- Адрес
- Россия, Москва, СЗАО
- Возраст
- 49
- Сообщений
- 2,144
- Записей в дневнике
- 1
Спасибо: Получено: 146
Отправлено: 16
0возможно форум что-то срезает
найти:
for($i = 0; $i <count>sql_query($sql)))
{
message_die(GENERAL_ERROR, 'Could not obtain matched posts list', '', __LINE__, __FILE__, $sql);
}
Когда запуск ?
-
24.02.2009, 15:20 #54
- Регистрация
- 18.04.2008
- Адрес
- Россия, Москва, ЮЗАО
- Возраст
- 45
- Сообщений
- 4,022
Спасибо: Получено: 15
Отправлено: 0
0Сообщение от autopilot
Когда запуск ?[/quote:2bc1bg4a]
гмм, да, чёт форум дурит с резалкой
должно быть так
сейчас проверяю на тестовом аккаунте.
нуна Директора подначить на операцию
правда придется форум закрыть на неск. часов, а то с базой опасно баловаться в рабочем режиме
-
24.02.2009, 15:53 #55
- Регистрация
- 06.03.2007
- Адрес
- Россия, Москва, СЗАО
- Возраст
- 49
- Сообщений
- 2,144
- Записей в дневнике
- 1
Спасибо: Получено: 146
Отправлено: 16
0$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 );
$phrase = str_replace('\\\"', '"', $phrase);
правда придется форум закрыть на неск. часов, а то с базой опасно баловаться в рабочем режиме
-
24.02.2009, 16:07 #56
- Регистрация
- 18.04.2008
- Адрес
- Россия, Москва, ЮЗАО
- Возраст
- 45
- Сообщений
- 4,022
Спасибо: Получено: 15
Отправлено: 0
0Сообщение от autopilot
$phrase = str_replace('\\"', '"', $phrase);
правда придется форум закрыть на неск. часов, а то с базой опасно баловаться в рабочем режиме
я просто "шкурный" интерес хочу внедрить, чтобы научить общепринятому языку запросов
т.е. уйти от OR, AND и NOT и заменить на +-""
впринципе как показывает практика, 99% юзеров просто пишут в поиск: ремонт турбины
и не заморачиваются на сложное построение запроса.
хмм ну это я так 20 000, вобщем можно действительно "деноминировать". я еще в процессе обдумывания рабочего варианта.
-
24.02.2009, 17:01 #57
- Регистрация
- 06.03.2007
- Адрес
- Россия, Москва, СЗАО
- Возраст
- 49
- Сообщений
- 2,144
- Записей в дневнике
- 1
Спасибо: Получено: 146
Отправлено: 16
0я просто "шкурный" интерес хочу внедрить, чтобы научить общепринятому языку запросов
По поиску можно редирект сделать. Еще немного разгрузит БД. После поиска (сложный запрос) идет сразу вывод результатов (еще один не простой запрос с выборкой из кучи таблиц). Можно разбить, занося результаты поиска в таблицу с временем "жизни" минут 30, юзеру страничку "подождите, сейчас вы будете перемещены к результатам поиска" с задержкой в 1-2 сек., ну и потом сами результаты.
Помоему в вобле такое есть. Но это уже за 5 минут не написать...
хмм ну это я так 20 000, вобщем можно действительно "деноминировать".
-
24.02.2009, 17:36 #58
- Регистрация
- 18.04.2008
- Адрес
- Россия, Москва, ЮЗАО
- Возраст
- 45
- Сообщений
- 4,022
Спасибо: Получено: 15
Отправлено: 0
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
ибо нафик? их мнооого накопилось
-
24.02.2009, 18:00 #59
- Регистрация
- 06.03.2007
- Адрес
- Россия, Москва, СЗАО
- Возраст
- 49
- Сообщений
- 2,144
- Записей в дневнике
- 1
Спасибо: Получено: 146
Отправлено: 16
0а вот кстати задержать пожалуй можно.
функцией DELAYED, если база занята, то поиск подождет
ну сторить еще тоже надо мудрить, я пока незнаю как это грамотно описать. моих мозгов не хватит
Ты же когда по страницам результатов поиска ходишь ничего заново не ищется. Посмотри строки с 675 по 760 (примерно) файла search.php результаты поиска заносятся в уже существующую таблицу и в дальнейшем используются. Именно это можно обыграть себе на пользу.
кстати перед бекапом, не почистить ли phpbb_search_results
ибо нафик? их мнооого накопилось
Добавлено спустя 2 минуты 49 секунд:
З.Ы.: У меня с 675 строки идет вот это:
//
// Delete old data from the search result table
//
-
24.02.2009, 18:07 #60
- Регистрация
- 18.04.2008
- Адрес
- Россия, Москва, ЮЗАО
- Возраст
- 45
- Сообщений
- 4,022
Спасибо: Получено: 15
Отправлено: 0
0Сообщение от autopilot
ну сторить еще тоже надо мудрить, я пока незнаю как это грамотно описать. моих мозгов не хватит
Ты же когда по страницам результатов поиска ходишь ничего заново не ищется. Посмотри строки с 675 по 760 (примерно) файла search.php результаты поиска заносятся в уже существующую таблицу и в дальнейшем используются. Именно это можно обыграть себе на пользу.[/quote]
это да, но это и так работает.
хотелось бы не переступить черту загрузки базы, отсрочить запрос если уже пошел аут.
кстати перед бекапом, не почистить ли phpbb_search_results
ибо нафик? их мнооого накопилось
ну я думаю Игорь точно скажет сколько там в них, но для этого форума prune не успевает, слишком много запросов они еще не состарились но их уже много.
Похожие темы
-
зачем такой коллектор на 1.8т?
от SergeyDonskoy в разделе VW Passat B5/В5+Ответов: 4Последнее сообщение: 08.10.2013, 17:20 -
Зачем испортили поиск ??
от vitek112 в разделе Курилка - МатюгалкаОтветов: 11Последнее сообщение: 02.12.2012, 16:07 -
поиск в ETKA
от Lucky3D в разделе Архив 2005г.Ответов: 10Последнее сообщение: 03.02.2005, 15:46 -
Чаво и зачем?
от Janet в разделе Архив 2004г.Ответов: 99Последнее сообщение: 15.12.2004, 16:18 -
при постановке защиты, сделали 2 дырки в усилителе бампера?
от Ира в разделе Архив 2004г.Ответов: 22Последнее сообщение: 15.11.2004, 12:55