【问题标题】:Separating keywords by space and searching MySQL database用空格分隔关键字并搜索 MySQL 数据库
【发布时间】:2012-03-11 14:22:26
【问题描述】:

我正在使用 PHP 和 MySQL。我将在下面提供一个简单的表格:

------------------------------------------------------
|  id |                    text                      |
------------------------------------------------------
|  1  | The quick brown fox jumped over the lazy dog | 
------------------------------------------------------

我希望用户能够使用以空格分隔的关键字进行搜索。我有一个简单的 SQL 查询,即SELECT * FROM table WHERE text LIKE %[$keyword]%,这意味着如果我搜索“The quick fox”,我不会得到任何结果。有没有办法用空格分隔关键字,所以如果我搜索“The quick fox”,它将运行 3 次搜索。一个用于“The”,一个用于“quick”,一个用于“fox” - 删除所有空格。虽然它应该只显示一个结果,因为它都属于同一行而不是 3 个,因为所有 3 个关键字都与该行中的数据匹配。

最好的方法是什么?总是欢迎所有能更好地做到这一点的建议。谢谢!

[编辑]

现在才想到,用逗号(,)分隔关键字会更好吗?

【问题讨论】:

  • 您几乎肯定应该在生成查询的代码中处理这个问题,而不是在 MySQL 中。 (另请参阅en.wikipedia.org/wiki/SQL_injection.
  • 感谢@ruakh 的关注。不过,我确实有。我只是不想把所有东西都放在一边,因为我想让人们专注于我所要求的东西。但是,再次感谢。
  • 好吧,但我坚持我的说法,你几乎肯定应该在生成查询的代码中处理这个问题,而不是在 MySQL 中。因此,为了获得最佳答案,您应该显示生成查询的代码。
  • 是的,@ruakh。这将是最好的方法之一 - 正如我所要求的那样。 :)

标签: mysql keyword sql-like


【解决方案1】:

您可以考虑使用regular expression via REGEXP 将单词分成一个或组。

SELECT * 
FROM tbl
WHERE
  LOWER(`text`) REGEXP '\b(the|quick|fox)\b'

匹配:

  • 棕色狐狸跳过懒狗
  • ,得到狐狸
  • 我吃了蛋糕

不匹配

  • 棕狗

在 PHP 中,您可以通过在空格上拆分搜索字符串并在转义每个组件后将其内爆回 | 来构造此表达式。

$str = "the quick brown fox";
$kwds = explode(" ", $str);
$kwds = array_map("mysql_real_escape_string", $kwds);
$regexp = "\b(" . implode("|", $kwds) . ")\b";

然后在你的声明中使用REGEXP '$regexp'

附录:

由于您在 OP 中没有提到它,我想确保您了解 MySQL 在 MyISAM 表上的全文搜索功能,以防它可以满足您的需要。根据您的描述,全文听起来并不完全符合您的要求,但您应该将其视为一种可能性:http://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html

【讨论】:

  • 你去。感谢您关注这个问题,我的朋友。让我试试你在这里包含的一些东西。
  • 我应该使用 [[:<:>:]] 代替 \b 吗?
  • 这似乎没有从“Qui”得到任何结果,它必须是“快速” - 任何解决方法?
  • @MikeSanchez 这种模式只会得到整个单词。如果您需要来自多个关键字的部分匹配,您将需要构建一个包含多个 LIKE 子句的查询以及一些用于削减它们的算法。
【解决方案2】:


我通过连接查询字符串的不同方法来做到这一点。

//此行包含四个用于搜索的单词
$str = "the quick brown fox";

//查询字符串写成小块,存储在变量“$uquery”中
$uquery = "select * from tablename where";

//一个新变量“$keywords”将值作为数组保存
$keywords = explode(" ", $str);
$关键字 = array_map("mysql_real_escape_string", $keywords);

//"$k" 将存储总数。数组中的元素数,在本例中应为“4”
$k = count($keywords);

//定义变量“$i”等于0
$i = 0;

//启动一个 while 循环,该循环将持续 4 次,因为我们在此示例中只有 4 个关键字
while($i

//这里又来了一个新的变量“$uquery_”,后面的部分会和之前的“$uquery”拼接起来
$uquery_ .= " topic like convert(_utf8 '%$keywords [$i]%' USING latin1)";

//为了更多的解释,让我告诉你“$keywords[$i]”将如何帮助上面的代码,对于“$i”的每个值,它将从数组中获取一个关键字,见下文:

//$keywords[0]= "the" for $i =0
//$keywords[1]= "quick" for $i =1
//$keywords[2]= "棕色" for $i =2
//$keywords[3]= "狐狸" for $i =3

//现在在 "$uquery_" 中的每一轮循环之后连接逻辑 && 运算符,但不是最后一轮,因为查询需要在最后一个关键字之后结束
if($i != $ k){ $uquery_ .= " &&"; }

//每轮后$i加1
$i++; }

//现在我们的主变量“$uquery”正在与“$uquery_”连接
$uquery .=“$uquery_”;

上面的代码将生成以下查询:

select * from tablename where topic like convert(_utf8 '%the%' USING latin1) && topic like convert(_utf8 '%quick %' USING latin1) && topic like convert(_utf8 '%brown%' USING latin1) && topic like convert(_utf8 '%fox%' USING latin1)

注意:“topic”应该是mysql表中的列名,您可以将其替换为您表中定义的列名。

我希望它能帮助一些人。如果您有任何问题,请随时通过我网站上的实时聊天功能向我提问 http://www.79xperts.com

问候

阿德南·赛义德

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-21
    • 2012-09-20
    • 2018-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多