【问题标题】:mysql: efficient way for postfix-search (like '%text' aka. prefix wildcard)?mysql:后缀搜索的有效方法(如“%text”又名前缀通配符)?
【发布时间】:2012-01-17 09:09:55
【问题描述】:

MySQL 中是否有任何内置功能可以在不扫描整个表的情况下执行上述操作?

我找到的唯一解决方案是存储我要比较的列的镜像版本并执行like 'txet%'

我也看不到绕过后缀搜索的方法。它适用于德语词典。许多单词都有一个带前缀的版本,例如用户搜索“Gericht”(英语简写),但知道有一个词“Amtsgericht”(英语区简写)也很有价值。不幸的是,德语中单词的两个部分通常没有空格分开。大约 15% 的查询实际上使用了前缀搜索。

【问题讨论】:

  • 看看mysql sphinx engineapache solr
  • 感谢狮身人面像的提示!这可以解决我面临的其他一些挑战,例如词干。对于这篇文章的问题,我将使用其他答案所证实的反列方法。这将是最快的解决方案,也是依赖最少的解决方案。

标签: mysql wildcard


【解决方案1】:

反向字段上的索引将是解决方案,有些人认为:

create index idx_reverse on table ( reverse( field ) );
select * from table where reverse(field) like 'txet%';

但 MySQL 不允许对表达式进行索引,仅对列进行索引:

这是MySQL create index syntax

CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEX index_name
    [index_type]
    ON tbl_name (index_col_name,...)
    [index_option] ...

这是postgres create index syntax

CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] name ON table [ USING method ]
    ( { column | ( expression ) } [ opclass ] [, ...] )
    ...

解决方法可以创建索引的第二个字段(字段 -> dleif)和一个mysql trigger 以保持反转字段:

alter table my_table add column dleif ...;
create index idx_reverse on my_table ( dleif );
Create Trigger `reverse_field` Before Update on `my_table` for each row BEGIN
    set new.dleif = reverse( new.field );
END;
select * from table where dleif like reverse('%text');

【讨论】:

    【解决方案2】:

    当您的值以通配符开头时,MySQL 不会使用索引。

    以相反的顺序存储第二列是一种防御方法。但是,它会在后缀上失败。

    如果您知道复合词,您可以预先计算“有价值的知识”匹配并将它们存储在另一个表中。我认为这不太可能适用于德语词典,但你可能知道一些我不知道的事情。

    【讨论】:

    • 感谢复合词的想法。我认为这对中缀搜索很有用(比如'%text%')。但是由于我正在做前缀或后缀而不是中缀,所以我将使用反向列方法。此外,虽然我是德国人,但首先需要对语法进行一些研究,我怀疑用德语构建复合词的可能性是无穷无尽的,因此需要大量数据。
    • 我以前住在德国。我的印象是,您可以用任何“n”个德语单词组成一个有效的复合词。而且'n'没有上限。
    • 是的,这是真的。一个典型的例子:Donaudampfschifffahrtsgesellschaft。它由五个名词 Donau、Dampf、Schiff、Fahrt 和 Gesellschaft 组成......:)
    猜你喜欢
    • 1970-01-01
    • 2018-04-15
    • 2014-08-12
    • 1970-01-01
    • 1970-01-01
    • 2022-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多