我有一个网站需要搜索大约 20-30k 条记录,其中大部分是电影和电视节目名称。该站点使用 memcache 运行 php/mysql。
我希望用我目前拥有的搜索来替换FULLTEXT
它soundex()
,它可以工作......有点,但在许多情况下并不是很好。
是否有任何体面的搜索脚本易于实现,并且将提供体面的搜索功能(表中的 3 列)。
我有一个网站需要搜索大约 20-30k 条记录,其中大部分是电影和电视节目名称。该站点使用 memcache 运行 php/mysql。
我希望用我目前拥有的搜索来替换FULLTEXT
它soundex()
,它可以工作......有点,但在许多情况下并不是很好。
是否有任何体面的搜索脚本易于实现,并且将提供体面的搜索功能(表中的 3 列)。
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 个字符)
如果您正在寻找一个简单的现有解决方案,而不是创建自己的解决方案,请查看
mysql中有一个函数SOUNDEX。如果要搜索电影名称:
select * from movie where soundex(title) = soundex( 'the title' );
当然,在文本中搜索不起作用,例如电影或情节摘要。
Soundex 是一个相对简单的算法。您还可以决定在应用级别处理所有这些,这可能更容易:
LIKE
在数据库级别使用常规。Soundex 在处理模糊搜索方面存在局限性。一个更好的功能是编辑距离,可以使用UDF集成到MySQL中。检查http://flamingo.ics.uci.edu/toolkit/以获取 Linux 上 MySQL 的 C++ 实现。