给出以下表结构:
id iata icao name
1 ANC PANC Anchorage - Ted Stevens International
2 LHR EGLL London - Heathrow
3 LGW EGKK London - Gatwick
4 MDZ SAME Mendoza - Governor Francisco Gabrielli International
以“最佳匹配优先”顺序提取记录的最佳方法是什么,正如您在旅行社网站的自动建议字段中所期望的那样?任何一列中="string"
上的匹配优先于任何其他列中LIKE "%string%"
上的匹配。在那之后,“名字”的字母顺序可能就是我想要的。
例如,搜索“anc”将返回第1行然后第4行。“lon”将返回3然后是2.
IATA代码始终为3个字符,ICAO始终为4.但是,其中一个或两个都可能为NULL。
虽然我希望我的AJAX能够提交三个字符并从那里过滤Javascript,我不能假设输入将是三个字符 - 非Javascript用户将提交任意长度的字符串。
我在PHP中使用MySQL进行此操作。
答案 0 :(得分:1)
这是一个难以破解的难题。以下是我过去使用的一些因素,其次是相对权重。
完全匹配将基于此得到100分(它匹配所有)。然后我简单地按重量加权排序。
对于我的数据集(歌曲名称),这产生了非常好的结果。不确定它是如何与你的相媲美的。
在你的情况下,我会添加一个“如果输入是3个字符,那么如果它匹配IATA则为50分,如果匹配ICAO则为50分,如果它与ICAO匹配”,则添加到列表中。
如何在SQL中执行此操作:
SELECT SUM(
IF(`name` = :Input, 50, 0),
IF(`iata` = :Input, 50, 0),
IF(`icao` = :Input, 50, 0),
IF(`name` LIKE CONCAT('%', :Input, '%'), 25, 0),
...
) FROM Table;
排序是在PHP中完成的。
不漂亮或优雅,但它有效。
答案 1 :(得分:1)
这是一个相当简单的方法:
SELECT ID, 1 As Certainty FROM airfields where iata = @searchValue OR icao = @searchValue OR name = @searchValue
UNION
SELECT ID, 2 FROM airfields where iata <> @searchValue AND icao <> @searchValue AND NAME <> @searchValue
AND (iata LIKE '%' + @searchValue + '%" OR icao LIKE '%' + @searchValue + '%" OR name LIKE '%' + @searchValue + '%")
ORDER BY Certainty
因此,完美匹配始终优先。你可能想在那之后收紧订单。
答案 2 :(得分:1)
如果您正在运行MyISAM类型表,请使用全文索引。匹配将为您提供相关性,您可以使用它来订购结果。 http://dev.mysql.com/doc/refman/5.5/en/fulltext-search.html#function_match
请改用Apache Solr或Sphinx。