5

我有一个网站需要搜索大约 20-30k 条记录,其中大部分是电影和电视节目名称。该站点使用 memcache 运行 php/mysql。

我希望用我目前拥有的搜索来替换FULLTEXTsoundex(),它可以工作......有点,但在许多情况下并不是很好。

是否有任何体面的搜索脚本易于实现,并且将提供体面的搜索功能(表中的 3 列)。

4

4 回答 4

7

ewemli 的答案是正确的,但是您应该将 FULLTEXT 和 soundex 映射结合起来,而不是替换全文,否则您的 LIKE 查询可能会很慢。

create table with_soundex (
  id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
  original TEXT,
  soundex TEXT,
  FULLTEXT (soundex)
);

insert into with_soundex (original, soundex) values 

('add some test cases', CONCAT_WS(' ', soundex('add'), soundex('some'), soundex('test'), soundex('cases'))),
('this is some text', CONCAT_WS(' ', soundex('this'), soundex('is'), soundex('some'), soundex('text'))),
('one more test case', CONCAT_WS(' ', soundex('one'), soundex('more'), soundex('test'), soundex('case'))),
('just filling the index', CONCAT_WS(' ', soundex('just'), soundex('filling'), soundex('the'), soundex('index'))),
('need one more example', CONCAT_WS(' ', soundex('need'), soundex('one'), soundex('more'), soundex('example'))),
('seems to need more', CONCAT_WS(' ', soundex('seems'), soundex('to'), soundex('need'), soundex('more')))
('some helpful cases to consider', CONCAT_WS(' ', soundex('some'), soundex('helpful'), soundex('cases'), soundex('to'), soundex('consider')))

select * from with_soundex where match(soundex) against (soundex('test'));
+----+---------------------+---------------------+
| id | original            | soundex             |
+----+---------------------+---------------------+
|  1 | add some test cases | A300 S500 T230 C000 | 
|  2 | this is some text   | T200 I200 S500 T230 | 
|  3 | one more test case  | O500 M600 T230 C000 | 
+----+---------------------+---------------------+

select * from with_soundex where match(soundex) against (CONCAT_WS(' ', soundex('test'), soundex('some')));
+----+--------------------------------+---------------------------+
| id | original                       | soundex                   |
+----+--------------------------------+---------------------------+
|  1 | add some test cases            | A300 S500 T230 C000       | 
|  2 | this is some text              | T200 I200 S500 T230       | 
|  3 | one more test case             | O500 M600 T230 C000       | 
|  7 | some helpful cases to consider | S500 H414 C000 T000 C5236 | 
+----+--------------------------------+---------------------------+

这给出了非常好的结果(在 soundex 算法的范围内),同时最大限度地利用了索引(任何查询 LIKE '%foo' 都必须扫描表中的每一行)。

注意对每个单词而不是整个短语运行 soundex 的重要性。您也可以在每个单词上运行自己的 soundex 版本,而不是让 SQL 来做,但在这种情况下,请确保在存储和检索时都这样做,以防算法之间存在差异(例如,MySQL 的算法不限制本身为标准的4 个字符

于 2009-12-16T08:29:57.243 回答
1

如果您正在寻找一个简单的现有解决方案,而不是创建自己的解决方案,请查看

于 2009-12-14T11:56:29.220 回答
0

mysql中有一个函数SOUNDEX。如果要搜索电影名称:

select * from movie where soundex(title) = soundex( 'the title' );

当然,在文本中搜索不起作用,例如电影或情节摘要。


Soundex 是一个相对简单的算法。您还可以决定在应用级别处理所有这些,这可能更容易:

  • 存储文本时,对其进行标记并将 soundex 应用于所有单词
  • 将原始文本和 soundex 版本存储在两列中
  • 当您搜索时,在应用程序中计算 soundex。级别,然后LIKE在数据库级别使用常规。
于 2009-12-14T08:40:22.070 回答
0

Soundex 在处理模糊搜索方面存在局限性。一个更好的功能是编辑距离,可以使用UDF集成到MySQL中。检查http://flamingo.ics.uci.edu/toolkit/以获取 Linux 上 MySQL 的 C++ 实现。

于 2013-03-14T16:03:56.943 回答