Php 从输入/选择的文本中查找类似内容
我有一个用户在他们的购物篮中有一个项目,例如:Gears Of War 2限量版-我希望能够显示其他项目,但不类似,更像不同版本,例如Gears Of War 2年度游戏版 所以我基本上想做的是,如果可能的话,用少一个单词进行搜索,如果没有找到任何单词,然后再进行搜索,直到得到所需的结果数,或者最终没有单词 因此,如果一个用户只是简单的“战争装备”,那么这很容易,因为有很多匹配,例如战争装备2,战争装备3等,当它是一个大的独特的标题Php 从输入/选择的文本中查找类似内容,php,mysql,Php,Mysql,我有一个用户在他们的购物篮中有一个项目,例如:Gears Of War 2限量版-我希望能够显示其他项目,但不类似,更像不同版本,例如Gears Of War 2年度游戏版 所以我基本上想做的是,如果可能的话,用少一个单词进行搜索,如果没有找到任何单词,然后再进行搜索,直到得到所需的结果数,或者最终没有单词 因此,如果一个用户只是简单的“战争装备”,那么这很容易,因为有很多匹配,例如战争装备2,战争装备3等,当它是一个大的独特的标题 这可行吗?这是最好的方法吗?如果您只需要一个MySQL调用就可
这可行吗?这是最好的方法吗?如果您只需要一个MySQL调用就可以做到这一点。然后创建一个具有简单循环的存储过程 将其放入循环中,并在每次迭代中删除一个单词
var_similar_title = 'Gears of War 2 Limited Edition'
....
SELECT
product_name
FROM
product
WHERE
product_name LIKE CONCAT(var_similar_title,'%')
....
删除单词的一种简单方法是结合使用REVERSE()、LOCATE()和SUBSTRING()函数
或
比如:
SET numWords = (length('gears of war')-length(REPLACE('gears of war', ' ', '')))/length(' ')
获取字符串中的单词数(或者,如果愿意,可以从php程序中传递),然后使用
SUBSTRING_INDEX('gears_of_war', i)
其中i最初为numWords,然后通过循环每次递减1
编辑:如果您需要更详细的示例,我将添加此示例:
DELIMITER $$
DROP PROCEDURE IF EXISTS findSimilarTitles$$
CREATE DEFINER=`root`@`localhost` PROCEDURE `findSimilarTitles`( title VARCHAR(255), minMatches INT)
BEGIN
DECLARE i INT;
DECLARE var_similar_title VARCHAR(255);
DECLARE var_number_of_matches INT;
SET i = 1;
SET i = (length(title)-length(REPLACE(title, ' ', '')))/length(' ');
WHILE i > 0 DO
SET title = SUBSTRING_INDEX(title, ' ', i);
SET var_number_of_matches = (SELECT COUNT(*) FROM products WHERE product_name LIKE CONCAT(title,'%'));
IF var_number_of_matches >= minMatches THEN
SET i = -99;
ELSE
SET i = i - 1;
END IF;
END WHILE;
IF i = -99 THEN
SELECT product_name FROM products WHERE product_name LIKE CONCAT(title,'%');
ELSE
SELECT 'No Matching Products';
END IF;
END$$
实现这一点的一种方法是,首先选择名称与当前产品使用相同单词的产品,然后根据匹配的单词数对其进行排序 我做了一个测试,并使用了一个使用此结构/内容的表格: 假设当前产品是id为1且标题为“Lorem ipsum dolor sit amet”的产品,我将标题拆分为多个单词,选择标题中至少有一个单词的产品,按照匹配的单词数对列表进行排序,并仅获得前几个单词(示例中为4个) 在此之后,为了确保获得更好的结果,而不仅仅是与最大字数匹配的结果,您可以使用类似levenshtein距离的字符串比较算法。我使用了这个算法,因为php核心中有一个函数用于此 基本上,此函数告诉您需要对字符串进行多少次转换才能到达另一个字符串(通过转换可以理解为:删除一个字符、添加一个字符或更改一个字符的值) 因此,通过获得初始标题和每个结果标题之间的levenshtein距离,您将知道更接近的标题 进行此操作时,您可以找到最小值(最好的值,因为它告诉您需要最小数量的变换),并显示找到此距离的产品 我在这里添加了一个示例脚本: 免责声明:您需要注意此脚本的安全性,这只是一个示例,并将其集成到您的系统中(此处,当前产品的product_id和product_name是静态变量) 另外:通过添加一些改进,您可以获得更好的结果,如:
- 执行一个从初始标题中删除的停止词列表(确保“和”、“或”等词不会得到“分”)
- 在获得分数之前,倒转单词,并为每个匹配的单词指定一个增长的表现,这样可以确保标题开头的单词比结尾的单词更重要
呼叫findSimilarTitles(,)
谢谢,这对我的学习非常有帮助,非常感谢。