Php 如何扫描MySQL中的所有字段以获取表单输入
在下面的脚本中,用户输入一个表单,如果行与用户输入的行相似,则从MYSQL表返回行。我正在建立一个搜索引擎,一切都是基于排名。但我希望能够调整下面的代码,看看“iPad”这个词出现行字段的次数,例如“title”、“description”、“keywords”和“link”。如果是这样,我希望该行返回的值高于id较高的行,但在所有字段的组合中仅提及一次iPad。 我的代码如下: 术语组合查询: $query=“选择*从扫描位置”Php 如何扫描MySQL中的所有字段以获取表单输入,php,Php,在下面的脚本中,用户输入一个表单,如果行与用户输入的行相似,则从MYSQL表返回行。我正在建立一个搜索引擎,一切都是基于排名。但我希望能够调整下面的代码,看看“iPad”这个词出现行字段的次数,例如“title”、“description”、“keywords”和“link”。如果是这样,我希望该行返回的值高于id较高的行,但在所有字段的组合中仅提及一次iPad。 我的代码如下: 术语组合查询: $query=“选择*从扫描位置” $terms=array\u map('mysql\u real
$terms=array\u map('mysql\u real\u escape\u string',$terms);
$i=0;
foreach($条款为每个$){
如果($i++!==0){
$query.=“和”;
}
$query.=“类似“{$each}%”的标题或类似“{$each}%”的链接或类似“{$each}%”的关键字或类似“{$each}%”的描述”;
}
$query=mysql\u query($query)或die('mysql查询错误:'.mysql\u错误($connect));
echo'Qlick在中显示了您的结果。数字格式($secs,2)。'秒。
';
$numrows=mysql\u num\u行($query);
如果($numrows>0){
while($row=mysql\u fetch\u assoc($query)){
$id=$row['id'];
$title=$row['title'];
$description=$row['description'];
$keywords=$row['keywords'];
$link=$row['link'];
$rank=$row['rank'];
独立术语查询
$query=“选择*从扫描位置”;
$terms=array\u map('mysql\u real\u escape\u string',$terms);
$i=0;
foreach($条款为每个$){
如果($i++!==0){
$query.=“或”;
}
$query.=“类似“{$each}%”的标题或类似“{$each}%”的链接或类似“{$each}%”的关键字或类似“{$each}%”的描述”;
}
//在循环结束之前,不要附加ORDER BY
$query=mysql\u query($query)或die('mysql查询错误:'.mysql\u错误($connect));
$numrows=mysql\u num\u行($query);
如果($numrows>0){
while($row=mysql\u fetch\u assoc($query)){
$id=$row['id'];
$title=$row['title'];
$description=$row['description'];
$keywords=$row['keywords'];
$link=$row['link'];
$rank=$row['rank'];
我会尝试使用一个辅助字段来执行此操作,在该字段上运行全文查询,您将在其中保存所有文本数据:
http://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html
另一种方法是在MySQL中运行过滤,在PHP中运行排名。在连接字段中运行一个LIKE可能会压缩一些性能
顺便说一句,您上面的代码在LIKE中缺少括号,因此结果将不正确:您不能询问字段1像'x'或字段2像'x'和字段1像'y'或…
,您必须说明在哪里(字段1像'x'或字段2像'x')和(字段1像'y'或…
)
现在,在OR的情况下,您可以对匹配的术语数量进行简单的排序(使用,并且该数量始终是术语的总数):
否则,在SQL中,您将需要求助于一个非常丑陋的黑客:
(LENGTH(
REPLACE(CONCAT(title,'|',link,'|',keywords),'{$term}','')
) - LENGTH(CONCAT(title,'|',link,'|',keywords)))/LENGTH('{$term}');
上面计算的是要进行搜索的文本的总长度与删除搜索字符串后相同文本的总长度之间的差值。该差值当然与搜索字符串存在的次数成正比:如果字符串长度为8个字符,则差值为32表示该字符串存在于将长度差除以项的长度,我们就得到了点击次数
问题是,对于一些术语,您必须使查询变得非常复杂,而且运行起来可能非常昂贵:
$select_fields = array('*');
$where = array();
$rank = array();
foreach($terms as $term)
{
// assume $term is NOT QUOTED
$search = mysql_real_escape_string($term);
$concat = "CONCAT(title,'|',link,'|',keywords)";
$where[] = "(${concat} LIKE '%{$search}%')";
$rank[] = "(LENGTH(REPLACE(${concat},'{$search}',''))
- LENGTH(${concat}))/LENGTH('{$search}')";
}
$select_fields[] = "(".implode(",", $rank).") AS ranking";
$query .= "SELECT " . implode(',', $select_fields)
. ' FROM scan WHERE (' . implode(' AND ', $where) . ')';
你正在嵌套mysql查询,这不是一个好主意。它可能适用于一个小数据集,但一旦你通过了几百行,游戏就结束了。
$select_fields[] '(' . implode ('+', $where) . ') AS ranking';
(LENGTH(
REPLACE(CONCAT(title,'|',link,'|',keywords),'{$term}','')
) - LENGTH(CONCAT(title,'|',link,'|',keywords)))/LENGTH('{$term}');
$select_fields = array('*');
$where = array();
$rank = array();
foreach($terms as $term)
{
// assume $term is NOT QUOTED
$search = mysql_real_escape_string($term);
$concat = "CONCAT(title,'|',link,'|',keywords)";
$where[] = "(${concat} LIKE '%{$search}%')";
$rank[] = "(LENGTH(REPLACE(${concat},'{$search}',''))
- LENGTH(${concat}))/LENGTH('{$search}')";
}
$select_fields[] = "(".implode(",", $rank).") AS ranking";
$query .= "SELECT " . implode(',', $select_fields)
. ' FROM scan WHERE (' . implode(' AND ', $where) . ')';