如何在sqlite db中有效地搜索整个单词

时间:2009-07-17 16:04:54

标签: iphone sql sqlite

我有一个有标题栏的表格。我想搜索像foo这样的整个单词。所以匹配“hi foo bye”o“foo”,但不是“foobar”或“hellofoo”。有没有办法不改变表结构来做到这一点?我目前使用3个相似的查询,但它太慢,我有“选择*来自'%foo'之类的标题或'foo%'或title ='foo'等标题或'%foo%'之类的标题; <登记/> 必须有更好的方法来做到这一点吗?

3 个答案:

答案 0 :(得分:1)

您可能对lucene,ferret或sphinx等搜索索引器感兴趣。这些将作为单独的进程运行,可以为您的数据建立索引,以便快速搜索可以配置词干等。

或者,根据您的数据,您可以在任何上下文中返回包含“foo”的所有结果,然后使用正则表达式或数据库之外的类型过滤它们。这可能是一项改进,具体取决于数据的特征。

答案 1 :(得分:0)

自发回答:

使用regexp 运算符代替 like 运算符。

编辑我刚刚意识到reitexp并不总是包含在SQLite中。你可能需要自己编译......换句话说,它默认不存在..

<强> 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

答案 2 :(得分:0)

您可以通过在构建中链接到iPhone应用程序中包含各种正则表达式库。

有关详细信息,请参阅this Stackoverflow question