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