我目前有一个搜索字段使用此代码搜索多个列:
$searchArray = explode(" ", $searchVal);
$query="SELECT * FROM users WHERE ";
$i=0;
foreach ($searchArray as $word) {
if ($i != 0) $query .= " OR ";
$query .= " MATCH (`first_name`, `last_name`, `email`) AGAINST ('".$word."*' IN BOOLEAN MODE)";
$i++;
}
假设我在表格中有这两行:
id | last_name | first_name | email
1 | Smith | John | john_smith@js.com
2 | Smith | Bob | bob_smith@js.com
如果我输入“John S”,只有第一个结果会显示所需的行为。
如果我输入“John Smith”,只有第一个结果会显示所需的行为。
如果我输入“Smith J”,即使 Bob 不匹配,两个结果都会显示。
如果我输入“Smith John”,即使 Bob 不匹配,两个结果都会显示。
最后,如果我输入“Jo S”,尽管“Jo”和“S”部分匹配,但不会返回任何结果。
谁能帮我修复我的查询以处理不重要的订单所需功能和部分结果匹配?如果它可以按最佳匹配(即单词的最长部分,从第一个字母开始,而不是中间的部分,在最多的列数中)进行排序,那也将是一个巨大的帮助。
更新:
只是想发布基于该解决方案的最终代码。我的循环创建多个匹配语句不正确,我的 ft_min_word_len 也是如此。
我的代码现在是:
$searchArray = explode(" ", $searchVal);
$query="SELECT * FROM users WHERE MATCH (`first_name`, `last_name`, `email`) AGAINST ('";
$i=0;
foreach ($searchArray as $word) {
$query .= "+".$word."* ";
}
$query .= "' IN BOOLEAN MODE)";
最佳答案
在 bool 模式下,要求字符串存在(而不是仅仅得分更高),通过 +
完成。前缀匹配以结尾的 *
完成。这似乎是你想要的,所以搜索:
+John* +S*
+John* +Smith*
+Smith* +J*
+Jo* +S*
请注意,全文索引无法帮助您搜索“单词中的任何位置”。所以像 *mith*
这样的东西肯定会失败:它们应该从索引中的字符 1 开始匹配。
如果您还想按匹配值对它们进行排序,例如,需要 John Smith
before Johnny Smithson
,您可以这样做这个:
SELECT * FROM user
WHERE MATCH(..fields..) AGAINST ('match' IN BOOLEAN MODE)
ORDER BY MATCH(..fields..) AGAINST ('match' IN BOOLEAN MODE) DESC;
除非您再次分别添加所有单词 >= ft_min_word_len
,否则您会看到什么地方也没有:
+John* +S* John
+John* +Smith* John Smith
+Smith* +J* Smith
+Jo* +S*
对于最后一个,两者都是<默认的 4 个字符,因此我们无法在默认的 mysql 中为其添加排序参数,但您可以根据需要设置不同的 ft_min_world_len
。
关于php - 如何进行部分单词匹配的多列mysql全文搜索,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15371951/