我目前只有一个搜索字段使用此代码搜索多个列:
$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不匹配,两个结果都会显示。
如果我输入“史密斯约翰”,两个结果都会显示,即使鲍勃不匹配。
最后,如果我输入“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)";
答案 0 :(得分:10)
在布尔模式下,要求字符串存在(而不是仅仅评分更高),使用+
完成。前缀匹配使用结尾*
完成。这似乎是你想要的,所以搜索:
+John* +S*
+John* +Smith*
+Smith* +J*
+Jo* +S*
请注意,全文索引无法帮助您搜索“单词中的任何位置”。因此*mith*
之类的东西必然会失败:它们的意思是与索引中的字符1匹配。
如果您还想按匹配值排序,例如,在 John Smith
之前需要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
不同的颜色。
答案 1 :(得分:2)
IN BOOLEAN MODE
您可以使用+
- 修饰符强制AND
或-
- 修饰符强制NOT
。没有操作员,你的情况,意味着可选。
您需要检查mysql配置中的最小字长,以使FULLTEXT INDEX索引字小于一定长度。
我必须设置
ft_min_word_len = 2
在my.cnf中并且不得不重建索引以使其有效。默认情况下为3.
找出你的min_word_len支票(和upvote)this question
答案 2 :(得分:2)
请参阅http://dev.mysql.com/doc/refman/5.5/en//fulltext-boolean.html
您可以在单词之前放置一个“+”,“ - ”或无运算符,使其搜索“AND包含该单词”,“NOT包含该单词”,并且没有运算符是“OR包含该单词”
如果我输入“John S”,则只有第一个结果显示所需的行为。
只有一个约翰,所以这是有效的,S低于最小字长并被丢弃
如果我输入“John Smith”,只有第一个结果显示哪个是所需的行为。
只有一个约翰,所以这是有效的
如果我输入“Smith J”,即使Bob不匹配,两个结果都会显示。
J低于最小字长,因此它唯一匹配的smith是行
如果我输入“史密斯约翰”,两个结果都会显示,即使鲍勃不匹配。
由于你处于BOOLEAN模式,MySQL将其解释为Smith或John ... Smith匹配两者。
最后,如果我输入“Jo S”,尽管“Jo”和“S”部分匹配,但不会返回任何结果。
Jo和S低于最小字长 - 我相信MySQL认为这不会搜索任何内容
您需要在搜索参数前添加“+”才能将其转换为AND搜索... +Smith +John