我有一个网站,在那里我可以索引有关电影的信息。要查找电影,用户可以输入电影的标题,此查询将发送到数据库:
SELECT IMDB, Name, Year, Views
FROM Movies
WHERE Name LIKE '%$search%'
我使用了"similar_text"函数来解决一些小错误。例如,如果名称是"低俗小说",用户键入:"低俗聚焦",因为我没有得到任何结果,所以我为每部电影运行这个小代码。
similar_text($search, $Name, $percent);
if ($percent > $ValMax) {
$ValMax = $percent;
$PosMax = $i;
}
我之所以使用这个代码,是因为我在数据库中只有几百部电影,而且在未来,它将最多达到两万部。此外,每部电影的标题平均为20个角色,而不考虑《奇爱博士》或《我如何学会停止担忧并爱上炸弹》等电影
真正的问题始于用户使用的一个查询:"Capitan America"(意大利语中美国队长的意思),电影的名字是"Captain America–Il primo vendicore"
使用Levenstein函数,我得到了可怕的结果,其中使用similar_text,它们至少是不错的。您可以在此处查看该查询的完整结果。我编了这个页面,看看每次搜索的Levenstein和相似的文本是什么。
如果我没有设置60%的障碍,我会选择的电影将是"C'era una volta in America"(《从前在美国》)。
然而,"Capitan America"answers"Captain America"非常相似,所以我想知道是否有办法检查每个单词。我也听说过Lucene,但我不知道如何开始,以及它是否适合我的需求。
感谢:)
1:
您可以使用SOUNDS LIKE
(作为MySQL字符串函数提供):
SELECT IMDB, Name, Year, Views FROM Movies WHERE Name SOUNDS LIKE '%$search%'
您可能希望在大型表上对其性能进行基准测试,因为'%$search%'
中前面的通配符意味着您的语句将无法使用任何索引。
2:
另一个可能的解决方案是为MySQL创建一个自定义的levenstein函数。在这里,你可以找到一个例子:
CREATE FUNCTION levenshtein( s1 VARCHAR(255), s2 VARCHAR(255) )
RETURNS INT
DETERMINISTIC
BEGIN
DECLARE s1_len, s2_len, i, j, c, c_temp, cost INT;
DECLARE s1_char CHAR;
-- max strlen=255
DECLARE cv0, cv1 VARBINARY(256);
SET s1_len = CHAR_LENGTH(s1), s2_len = CHAR_LENGTH(s2), cv1 = 0x00, j = 1, i = 1, c = 0;
IF s1 = s2 THEN
RETURN 0;