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

Форум PHP

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

 

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

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

тема: Регулирование потребляемой памяти
 
 автор: Wyfinger   (09.03.2010 в 05:51)   письмо автору
 
 

Добрый день.

У меня на сайте есть небольшая текстовая база (~1000 master записей и еще ~600 detail). На сайте есть поиск. Сделан по следующей схеме: сначала ищется в Master записях (ищется в разных полях, в зависимости от того в каком поле найдено Rank умножается на весовой коэффициент) затем ищется в Detail и по MasterID (ссылке на Master запись в Detail) ищутся еще записи, которые добавляются к уже найденному. Потом удаляются дубликаты и сортируется о Rank'у.
Поиск сделан именно так, чтобы если поисковой запрос был найден в названии книги (условно) этот результат был в выдаче выше, чем если в в описании, а если в комментарии - ниже, чем если в описании. Т.е. Релевантность. Также в скрипте производится цитаты, тоже довольно требовательный, надо полагать, процесс.

Теперь о проблеме - стал замечать, что иногда у меня поиск не работает - стал выяснять, говорит не хватает памяти. У хостера установлено ограничение на 10 Mb для PHP. Теперь не знаю что и делать.

Подскажите как такие проблемы вообще решать?

Приведу код (сильно не пинайте пожста):
<?php
....
// Получение 
$keys str_replace(array("'"'"'';'','),
  array(
''''' '' '),
  
trim($_GET['q']));
$keys explode(' '$keys);
$keys array_unique($keys);
$key_count count($keys);
// Считаем длинну слов для поиска
$key_count count($keys);
for(
$i=0$i<$key_count$i++) {
    
$nkeys[$i][0] = strlen($keys[$i]);
    
$nkeys[$i][1] = $keys[$i];
}
// Отсортируем по длинне ключевых слов и выделим пять самых больших слов
rsort($nkeys);
unset(
$keys);
if(
$key_count>5)  $key_count 5;
for(
$i=0$i<$key_count$i++) {
    
$keys[$i] = $nkeys[$i][1];
    
// Это для вывода
    
$akeys .= $keys[$i]." ";
    
$bold_keys[] = "<strong>".$keys[$i]."</strong>";
}
unset(
$nkeys);
$keys array_slice($keys05);
 
// Если самое длинное слово короче 4 символов, вернем предупреждение
global $bold_keys;
$akeys substr($akeys0strlen($akeys)-1);
$max_length strlen($keys[0]); 
if(
$max_length<=3) {
    die(
"Слишком короткие слова в поисковом запросе, как минимум одно слово должно быть длиннее 3 символов");
}
 
// У нас будет отдельный поисковой запрос для каждого слова
for($i=0$i<$key_count$i++) {
    
$key $keys[$i];
    
$query "# Поиск в базе с дубликатами
        SELECT `Id`, 2 AS `Rank` FROM `books` WHERE `bookName` LIKE \"%
$key%\" UNION
        SELECT `Id`, 1 AS `Rank` FROM `books` WHERE `bookAuthors` LIKE \"%
$key%\" UNION
        SELECT `Id`, 0.5 AS `Rank` FROM `books` WHERE `bookYear` LIKE \"%
$key%\" UNION
        SELECT `Id`, 0.7 AS `Rank` FROM `books` WHERE `bookDescript` LIKE \"%
$key%\" UNION
        SELECT MIN(`bookId`) AS Id, COUNT(*)/5 AS `Rank` FROM `comments`  WHERE `aText` LIKE \"%
$key%\"  GROUP BY `bookId`, `aText`";
    
$result mysql_query($query) or die("Query failed : " mysql_error());
    while(
$row mysql_fetch_array($resultMYSQL_ASSOC)) {
        
$sresult[] = $row;
    }
}
 
if(
count($sresult)>0) {
 
    
// Теперь нужно пересчитать релевантность: если Id посторяется - сложить Rank и оставить одну запись
    
$i 0;
    while(isset(
$sresult[$i])) {
        
$temp_count count($sresult);   // Потому-что размер массива мужет уменьшиться
        
for($j=$temp_count-1$j>$i$j--) {
            if(
$sresult[$i]['Id']==$sresult[$j]['Id']) {
                
$sresult[$i]['Rank'] += $sresult[$j]['Rank'];
                
array_splice($sresult$j1);
            }
        }
        
$i++;
    }
 
    
// Отсортируем по релевантности
    
function wy_cmp($a$b) {
        if (
$a['Rank'] == $b['Rank']) {
            return 
0;
        }
        return (
$a['Rank'] < $b['Rank']) ? : -1;
    }
    
usort($sresult"wy_cmp");
    
$sresult array_slice($sresult020);
 
    
// Получение небольшой цитаты с выделенными ключевыми словами
    
function getQuoting($bookId$keys) {
        global 
$bold_keys;
        
// Получим полный текст описания книги из авторов, названия, года, описания и комментариев
        
$result mysql_query("SELECT * FROM `books` WHERE `Id`=$bookId");
        
$result mysql_fetch_array($resultMYSQL_ASSOC);
        
$bookDescript $result['bookDescript'];
        
$text $result['bookAuthors'].' / '.$result['bookName'].' / '.$result['bookYear']."\n".$result['bookDescript']."\n";
        
$result mysql_query("SELECT * FROM `comments` WHERE `bookId`=$bookId");
        while(
$row mysql_fetch_array($resultMYSQL_ASSOC)) {
            
$text .= $row['aText']."\n";
        }
        
// Теперь сделаем цитату: слева и справа от ключевых слов оставим по 20-25 символов
        
$quote_left 25// количество символов слева и справа от ключевых слов
        
for($i=0$i<count($keys); $i++) {
            
$key_pos strpos(strtolower($text), strtolower($keys[$i]));
            
// Заполняем массив $anchors - это предполагаемые позиции начала и конца цитаты
            
if($key_pos !== FALSE) {
                if((
$key_pos $quote_left)<0) {
                    
$anchors[] = 0;
                } else {
                    
$anchors[] = $key_pos $quote_left;
                }
                if((
$key_pos strlen($keys[$i]) + $quote_left)>strlen($text)) {
                    
$anchors[] = strlen($text);
                } else {
                    
$anchors[] = $key_pos strlen($keys[$i]) + $quote_left;
                }
            }
        }
        
// Если цитаты пересекаются - объеденим их
        
for($i=1$i<count($keys); $i=$i+2) {
            if((isset(
$anchors[$i+1])) & ($anchors[$i]-$anchors[$i+1]>=0)) {
                
array_splice($anchors$i2);
            }
        }
        
// Формирование текста цитаты
        
for($i=0$i<(count($anchors)-1); $i=$i+2) {
            
$quote .= '... '.str_replace($keys$bold_keyssubstr($text$anchors[$i], $anchors[$i+1]-$anchors[$i]))." \n";
        }
        
// Если цитата пустая просто выведем первые 200 символов описания
        
if(($quote=='... ') | ($quote=='')) {
            
$quote substr($bookDescript0200);
        }
        return 
$quote." ...";
 
    }
 
    
// Составляем вывод вместе с цитатами
    
$list_code '<div class="title">Результаты поиcка по запросу: '."'$akeys'".'</div>'."\n<ol>";
    for(
$j=0$j<count($sresult); $j++) {
        
$list_code .= '<li> <a href="'.SITE_WWW.'book.php?id='.$sresult[$j]['Id'].'">'.
            
getBook($sresult[$j]['Id'], 'bookAuthors').' / '.getBook($sresult[$j]['Id'], 'bookName').' / '.
            
getBook($sresult[$j]['Id'], 'bookYear').'</a></li>'.
            
'<div class="search_quote">'.getQuoting($sresult[$j]['Id'], $keys)."</div>\n";
        
$i++;
    }
    
$list_code .= '</ol>';
}
 
// К выдаче внутреннего поискового движка добавим не более 10 результатов поиска от Yandex

.....
?>

  Ответить  
 
 автор: Wyfinger   (10.03.2010 в 09:01)   письмо автору
 
   для: Wyfinger   (09.03.2010 в 05:51)
 

Может кто-нибудь ответит чего по-существу?!..

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

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