2016-04-29 6 views
1

Я новичок на этом сайте.Perl MySQL Полный текст Поиск

У меня есть следующий код для поиска по трем столбцам с полным текстом. (Searchdatabase.title, searchdatabase.keywords, searchdatabase.description)

$SQL_QUERY=<<__CURSOR_1__; 
select distinct url, keywords, description, title from searchdatabase 
where match (searchdatabase.title, searchdatabase.keywords, 
searchdatabase.description) against ('$datasent' IN BOOLEAN MODE) 
order by authority_rank desc, rank desc limit 10 offset $page; 
__CURSOR_1__ 


$dbh = DBI -> connect ($dns, $username, $password) 
or &Error("Can not connect to database."); 

$cursor = $dbh->prepare("$SQL_QUERY"); 
$cursor->execute; 

С моим ограниченным знанием Perl поиска полнотекстового и SQL, у меня есть следующий код, прежде чем приведенный выше код, чтобы сделать некоторые профилактики инъекции SQL и сделать пробелы " + "для поиска.

$datasent =~ s//+/g; 
$datasent =~ s/ / +/g; 
$datasent =~ s/\n//g; 
$datasent =~ s/<//g; 
$datasent =~ s/\x00//g; 
$datasent =~ s/\r//g; 
$datasent =~ s/\x1a//g; 
$datasent =~ s/\;//g; 
$datasent =~ s/\*//g; 
$datasent =~ s/\'//g; 
$datasent =~ s/\"//g; 

Это правильный способ сделать это? У меня есть чувство, что что-то не так с созданием пробелов в «+» ...

+2

Спасибо за предложение, я редактировал код так, что он подходит. Теперь лучше? –

ответ

3

DBI's placeholders - это путь сюда. Он позаботится о том, чтобы сбежать от вас.

my $sql = <<'CURSOR_1'; 
select distinct url, keywords, description, title 
from searchdatabase where 
match (searchdatabase.title, searchdatabase.keywords, searchdatabase.description) 
against (? IN BOOLEAN MODE) 
order by authority_rank desc, rank desc limit 10 offset $page; 
CURSOR_1 

Вы в основном положили ? в запрос. Когда вы его вызываете, передайте параметры в execute.

my $sth = $dbh->prepare($sql); 
$cursor->execute($datasent) ; 

Для $page это не будет работать, потому что это не входит в предложении WHERE. Вместо этого вы должны просто убедиться, что он содержит число, если оно приходит извне.

die 'offset needs to be numeric' if $page =~ /\D/; 

Поскольку вы новый пользователь, вот несколько замечаний о вашем коде:

  • всегда use strict и use warnings – они делают вашу жизнь проще
  • затем объявить переменные с my
  • $ALL_CAPS переменные обычно используются для переменных глобалов в Perl
  • в контексте DBI, заявление ручки обычно называют $sth
  • не используют амперсанд в &foo(), он не делает то, что вы думаете
  • вам не нужно ставить одиночные переменные в двойные кавычки для интерполяция
+1

Большое спасибо, что ограничение и смещение имеют местозаполнитель, а также место в BOOLEAN MODE сделали трюк! –

+0

@TsubasaKato рад, что я мог бы помочь. Пожалуйста, примите [тур], чтобы узнать, как принять ответ, если он решил вашу проблему :) – simbabque

0

В дополнение к замечательным предложениям @ simbabque, позвольте мне объяснить замену +.

Полный текст поиска BOOLEAN режим, по умолчанию, вероятно, не делает то, что вы ожидаете. «По умолчанию (когда ни + ни - не указано) слово не является обязательным, но строки, содержащие его, имеют более высокий рейтинг ...» См. Mysql Docs.

Так что если ваш пользователь ищет red apple, он получит что-нибудь с «красным» ИЛИ «яблоком» в некотором приоритете, решаемом mysql. Что вы можете решить, скорее всего, не то, что они хотят. Таким образом, на заднем конце вы можете заменить поиск пользователя +red +apple, который сообщает mysql искать «красное яблоко».

Это то, что у меня есть

$datasent =~ s/[+\-<>)(]/ /g;  #These have special meaning in the sql search that people probably don't want. 
$datasent =~ s/(".*?"|\S+)/+$1/g; #Add '+' for the boolean search and pay attention to quotes. 
+0

Да, именно это я и хотел выяснить первым. Я забыл добавить немного к части $ datasent. Я закодировал '$ datasent =" \ + $ datasent ";' перед линиями + замены. Это верно? –

+0

В подобном коде у меня есть, я сначала вычеркиваю все символы «+» и «-», а затем снова добавляю их, обращая внимание на цитируемые строки. Я могу обновить свой ответ этой информацией, но не могу дойти до него прямо сейчас. – Mort

+0

Благодарим за предложение. Я постараюсь выяснить, как вы это делали. –