MySQL - 如何在此全文搜索中插入额外的where子句

时间:2010-06-07 19:47:00

标签: mysql full-text-search

我想在全文搜索查询中添加一个WHERE子句(限制为过去24小时),但无论我在哪里插入它都会出现低级别错误。是否可以添加该条款,若然,如何?这是没有where子句的代码:

        $query = "SELECT *, MATCH (story_title) AGAINST ('$query' IN BOOLEAN MODE) 
AS Relevance FROM stories WHERE MATCH (story_title) AGAINST ('+$query' IN BOOLEAN MODE)
 HAVING Relevance > 0.2 ORDER BY Relevance DESC, story_time DESC;

2 个答案:

答案 0 :(得分:5)

首先,提出问题的一些提示:

  • 使用换行符。 PHP支持带换行符的字符串文字,与Java等语言不同。格式化SQL使其更易于阅读,调试和维护。

  • 显示SQL。您在该查询中嵌入了PHP变量扩展,这与您的问题无关。这使得人们更难以破译你想要问的内容。显示要调试的代码,而不是生成代码的代码。

现在关于你的查询:

  • 您不能在任何地方添加额外的WHERE条款。使用WHERE运算符为现有AND子句添加额外的术语。

  • 在同一查询中多次嵌入调用以验证相同的$_GET参数似乎很浪费。使用变量来保留验证参数的结果。

  • 利用short-circuit evaluation。将最便宜的条件(例如那些受益于传统指数的条件)放在最左边。

  • boolean mode中的MySQL全文搜索未返回相关性。您必须使用natural language mode来获取0和1之间的相关性值。

  • 将条件放在HAVING子句而不是WHERE子句中会更容易,因为您可以使用在SELECT列表中定义的列别名,但它可能会使查询表现更差。 HAVING用于在组GROUP BY子句后包含条件。 WHERE用于在行上放置条件以包含在查询结果中。

  • 如果在MATCH()子句中以自然语言模式使用WHERE,则行会按相关性顺序自动排序。如果平局的可能性很低,您可以跳过ORDER BY子句,并使查询更有效率。

以下是我编写此代码的方法:

$q = validate_input($_GET["q"]);
$bsearch = $pdo->quote("+{$q}");
$nlsearch = $pdo->quote($q);
$stories_table = $config["db"]["pre"] . "stories";
$offset = validate_input(($_GET["page"]-1)*10);

$query = "
  SELECT *, MATCH (story_title) AGAINST ({$nlsearch}) AS Relevance 
  FROM {$stories_table} 
  WHERE story_time > time()-86400
    AND MATCH (story_title) AGAINST ({$bsearch} IN BOOLEAN MODE) 
    AND MATCH (story_title) AGAINST ({$nlsearch}) > 0.2
  LIMIT {$offset}, 10";

答案 1 :(得分:0)

看起来你有两个WHERE条款:

SELECT * 
WHERE story_time > time()-86400 
AND MATCH (story_title) AGAINST ('".validate_input($_GET['q'])."' IN BOOLEAN MODE) 
AS Relevance 
FROM ".$config['db']['pre']."stories 
WHERE MATCH (story_title) AGAINST ('+".validate_input($_GET['q'])."' IN BOOLEAN MODE) 
HAVING Relevance > 0.2 
ORDER BY Relevance DESC, story_time DESC LIMIT 

应该是这样的:

SELECT *, MATCH (story_title) AGAINST ('".validate_input($_GET['q'])."' IN BOOLEAN MODE) 
AS Relevance 
FROM ".$config['db']['pre']."stories 
WHERE MATCH (story_title) AGAINST ('+".validate_input($_GET['q'])."' IN BOOLEAN MODE) 
HAVING Relevance > 0.2 
AND story_type > time() - 86400
ORDER BY Relevance DESC, story_time DESC LIMIT