【发布时间】:2009-07-17 16:04:54
【问题描述】:
我有一个包含标题列的表格。我想搜索像 foo 这样的整个单词。所以匹配“hi foo bye”或“foo”,但不能匹配“foobar”或“hellofoo”。有没有办法不改变表结构来做到这一点?我目前使用 3 个类似查询,但它太慢了,我有“从文章中选择 *,其中标题如 '% foo' 或标题如 'foo %' 或 title = 'foo' 或标题如 '% foo %'; 一定有更好的方法来做到这一点?
【问题讨论】:
我有一个包含标题列的表格。我想搜索像 foo 这样的整个单词。所以匹配“hi foo bye”或“foo”,但不能匹配“foobar”或“hellofoo”。有没有办法不改变表结构来做到这一点?我目前使用 3 个类似查询,但它太慢了,我有“从文章中选择 *,其中标题如 '% foo' 或标题如 'foo %' 或 title = 'foo' 或标题如 '% foo %'; 一定有更好的方法来做到这一点?
【问题讨论】:
您可能对 lucene、ferret 或 sphinx 等搜索索引器感兴趣。这些将作为单独的进程运行,这些进程将为您的数据编制索引,以便快速搜索可以配置词干等的位置。
或者,根据您的数据,您可以在任何上下文中返回所有包含“foo”的结果,然后使用正则表达式或数据库外部的此类过滤它们。这可能会有所改进,具体取决于您的数据特征。
【讨论】:
自发回答:
使用正则表达式 operator 而不是 like 运算符。
编辑 我刚刚意识到 SQLite 并不总是包含 regexp。您可能必须自己编译...换句话说,默认情况下它不存在..
EDIT2
这是一个有效的 Perl 示例 ..
#!/usr/bin/perl -w
use strict;
use Data::Dumper;
use DBI;
# connect to the DB
my $dbh = DBI->connect("dbi:SQLite:dbname=dbfile","","");
# create ugly, pureperl function 'regexp'
# stolen from http://d.hatena.ne.jp/tokuhirom/20090416/1239849298
$dbh->func( "regexp"
, 2
, sub { my ( $pattern, $target ) = @_;
utf8::decode($pattern);
utf8::decode($target);
$target =~ m{$pattern} ? 1 : 0;
}
, "create_function" );
# drop table, if it exists
$dbh->do('drop table if exists foobar');
$dbh->do('create table foobar (foo varchar not null)');
my $sth=$dbh->prepare('insert into foobar (foo) values (?)');
while (<DATA>) { chop;$sth->execute($_); }
#query using regexp
my $a= $dbh->selectall_arrayref( 'select foo '
.'from foobar '
.'where foo regexp "^foo$|^foo\s+.*|.*\W+foo\W+.*|.*\W+foo$"'
);
print join("\n", map {$_->[0];} @{$a})
__DATA__
foo
foo
barfoo
foobarfolo
sdasdssds bar dasdsdsad
dasdsdasdsadsads foo! dasdasdasdsa
【讨论】:
您可以通过在构建中链接到各种正则表达式库来将它们包含在您的 iPhone 应用程序中。
更多信息请参见this Stackoverflow question。
【讨论】: