Perl MySQL 全文搜索
Perl MySQL Fulltext Search
我是这个网站的新手。
我有以下代码来搜索具有全文索引的三列。 (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;
这样做正确吗?
我觉得把空格变成“+”有点不对...
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()
中使用 & 符号,它不会像你想的那样
- 您不需要将单个变量放入双引号中进行插值
除了@simbabque 的好建议之外,让我解释一下 +
替换。
全文搜索 BOOLEAN
模式,默认情况下可能不会执行您期望的操作。 "By default (when neither + nor - is specified) the word is optional, but the rows that contain it are rated higher... " 参见 Mysql Docs。
因此,如果您的用户搜索 red apple
,他们将获得带有 "red" 或 "apple" 的任何内容,优先级由 mysql 决定。您可能决定的可能不是他们想要的。所以在后端,你可以用 +red +apple
替换用户的搜索,这告诉 mysql 搜索 "red AND apple".
这就是我的
$datasent =~ s/[+\-<>)(]/ /g; #These have special meaning in the sql search that people probably don't want.
$datasent =~ s/(".*?"|\S+)/+/g; #Add '+' for the boolean search and pay attention to quotes.
我是这个网站的新手。
我有以下代码来搜索具有全文索引的三列。 (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;
这样做正确吗? 我觉得把空格变成“+”有点不对...
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()
中使用 & 符号,它不会像你想的那样 - 您不需要将单个变量放入双引号中进行插值
除了@simbabque 的好建议之外,让我解释一下 +
替换。
全文搜索 BOOLEAN
模式,默认情况下可能不会执行您期望的操作。 "By default (when neither + nor - is specified) the word is optional, but the rows that contain it are rated higher... " 参见 Mysql Docs。
因此,如果您的用户搜索 red apple
,他们将获得带有 "red" 或 "apple" 的任何内容,优先级由 mysql 决定。您可能决定的可能不是他们想要的。所以在后端,你可以用 +red +apple
替换用户的搜索,这告诉 mysql 搜索 "red AND apple".
这就是我的
$datasent =~ s/[+\-<>)(]/ /g; #These have special meaning in the sql search that people probably don't want.
$datasent =~ s/(".*?"|\S+)/+/g; #Add '+' for the boolean search and pay attention to quotes.