我正在使用 php 和 mySql 创建一个网络应用程序。
它基本上是一个带有单个文本框的简单搜索表单。
用户输入可以是关键字的组合,为此我在 string_ireplace() 之后使用了 php explode() 函数。
现在我想针对单个表中的每个字段(比如 filed 1、filed 2、......字段 n)搜索每个关键字(比如 val 1、val 2、..... val n) .
我觉得我将不得不使用多个 for 循环 - 为每个值搜索所有字段。
但是我怎样才能根据相关性对结果进行排序,即。匹配所有值的记录将首先出现,依此类推。
由于此表排序不是在数据库级别进行的,因此我无法使用 ORDER BY 子句。
编辑:好的。我想我必须详细解释我正在寻找什么以及我已经取得了什么。以下是我写的代码,它几乎达到了我的目的,但看起来很耗时(执行)。
<?php
//$str = mysql_real_escape_string($_GET['searchText']);
$str = "val1, val2, val3";
$str = trim($str);
// check for an empty string and display a message.
if ($str == "") {
$resultmsg = "<p>Search Error: Please enter a search keyword...</p>" ;
}
$str = explode(",",$str);
//Create array for all fields
$fields = array("filed1","filed2","filed3","filed4");
$condition = "";
for ($j=0;$j<count($str);$j++){
for ($i=0;$i<count($fields);$i++){
$condition = $condition.$fields[$i]." = '".$str[$j]."' OR ";
}
$condition = rtrim($condition, " OR");
$condition = $condition.") AND (";
}
$condition = rtrim($condition, " AND (");
$sql = "SELECT * FROM TABLE WHERE (".$condition;
echo $sql;
echo "<br /><hr>";
$condition = "";
for ($j=0;$j<count($str);$j++){
for ($i=0;$i<count($fields);$i++){
$condition = $condition.$fields[$i]." = '%".$str[$j]."%' OR ";
}
$condition = rtrim($condition, " OR");
$condition = $condition.") AND (";
}
$condition = rtrim($condition, " AND (");
//$condition = str_replace("="," LIKE ",$condition);
$sql= "SELECT * FROM TABLE WHERE (".$condition;
echo $sql;
echo "<br /><hr>";
//testing
if (count($str)==3){
$condition = "";
for ($j=0;$j<count($str)-1;$j++){
for ($i=0;$i<count($fields);$i++){
$condition = $condition.$fields[$i]." = '%".$str[$j]."%' OR ";
}
$condition = rtrim($condition, " OR");
$condition = $condition.") AND (";
}
$condition = rtrim($condition, " AND (");
//$condition = str_replace("="," LIKE ",$condition);
$sql= "SELECT * FROM TABLE WHERE (".$condition;
echo "<strong>Matching ".$str[0]." AND ".$str[1]."<br /></strong>";
echo $sql;
echo "<br /><hr>";
$condition = "";
for ($j=1;$j<count($str);$j++){
for ($i=0;$i<count($fields);$i++){
$condition = $condition.$fields[$i]." = '%".$str[$j]."%' OR ";
}
$condition = rtrim($condition, " OR");
$condition = $condition.") AND (";
}
$condition = rtrim($condition, " AND (");
//$condition = str_replace("="," LIKE ",$condition);
$sql= "SELECT * FROM TABLE WHERE (".$condition;
echo "<strong>Matching ".$str[1]." AND ".$str[2]."<br /></strong>";
echo $sql;
echo "<br /><hr>";
$condition = "";
for ($j=0;$j<count($str);$j=$j+2){
for ($i=0;$i<count($fields);$i++){
$condition = $condition.$fields[$i]." = '%".$str[$j]."%' OR ";
}
$condition = rtrim($condition, " OR");
$condition = $condition.") AND (";
}
$condition = rtrim($condition, " AND (");
//$condition = str_replace("="," LIKE ",$condition);
$sql= "SELECT * FROM TABLE> WHERE (".$condition;
echo "<strong>Matching ".$str[2]." AND ".$str[0]."<br /></strong>";
echo $sql;
echo "<br /><hr>";
}
?>
我得到的输出如下:
完全匹配所有值
SELECT * FROM TABLE WHERE (filed1 = 'val1' OR filed2 = 'val1' OR filed3 = 'val1' OR filed4 = 'val1') AND (filed1 = 'val2' OR filed2 = 'val2' OR filed3 = ' val2' OR filed4 = 'val2') AND (filed1 = 'val3' OR filed2 = 'val3' OR filed3 = 'val3' OR filed4 = 'val3')
部分匹配所有值
SELECT * FROM TABLE WHERE (filed1 = '%val1%' OR filed2 = '%val1%' OR filed3 = '%val1%' OR filed4 = '%val1%') AND (filed1 = '%val2%' OR filed2 = '% val2%' OR filed3 = '% val2%' OR filed4 = '% val2%') AND (filed1 = '% val3%' OR filed2 = '% val3%' OR filed3 = '% val3%'或 filed4 = '% val3%')
匹配 val1 和 val2
SELECT * FROM TABLE WHERE (filed1 = '%val1%' OR filed2 = '%val1%' OR filed3 = '%val1%' OR filed4 = '%val1%') AND (filed1 = '%val2%' OR filed2 = '% val2%' OR filed3 = '% val2%' OR filed4 = '% val2%')
匹配 val2 和 val3
SELECT * FROM TABLE WHERE (filed1 = '% val2%' OR filed2 = '% val2%' OR filed3 = '% val2%' OR filed4 = '% val2%') AND (filed1 = '% val3%' OR filed2 = '% val3%' OR filed3 = '% val3%' OR filed4 = '% val3%')
匹配 val3 和 val1
SELECT * FROM TABLE WHERE (filed1 = '%val1%' OR filed2 = '%val1%' OR filed3 = '%val1%' OR filed4 = '%val1%') AND (filed1 = '%val3%' OR filed2 = '% val3%' OR filed3 = '% val3%' OR filed4 = '% val3%')
我现在可以继续将获取的数据附加到我的结果表中。但不知何故,我觉得这不是一个明智的解决方案。此外,我对搜索值的数量有限制(例如,此处为 3)。我希望我能够解释我到底在寻找什么。
最佳答案
这是一个答案,它处理可扩展性(限制用户可以搜索的关键字数量)和按相关性排序(每张 map 匹配关键字的数量)的问题。我删除了检查空值之类的东西,但我添加了一些东西;阅读评论,看看是什么。还没有测试过,所以我不知道它的性能如何......
<?php
$str = preg_split('/[\s,\+]+/', $str); // splits $str into individual words when
// it finds spaces, commas, and/or plus
// signs. This way, you won't have to
// force users to use plus signs
$fields = array('field1', 'field2', 'field3', 'field4');
foreach ($keywords as $i => $keyword) {
// escapes and quotes those keywords to prevent against injection attack
$keywords[$i] = '"' . mysql_real_escape_string($keyword) . '"';
}
// concatenates the keywords into one string that we can use as a set in
// MySQL's IN() clause
$keywords = implode(',', $keywords);
$fieldSearchQueries = array ();
foreach ($fields as $thisField) {
// here's the IN() clause, checking each field against the set of keywords
$fieldSearchqueries[] = 'CASE WHEN ' . $thisField . ' IN (' . $keywords . ')'
. ' THEN 1 ELSE 0 END';
}
$query = 'SELECT *, ' . implode(' + ' $fieldSearchQueries) . ' AS rank '
. 'FROM TABLE WHERE rank > 0 ORDER BY rank';
?>
这应该创建一个类似这样的查询:
SELECT *,
CASE WHEN field1 IN ('India', 'Rainfall', 'English') THEN 1 ELSE 0 END
+ CASE WHEN field2 IN ('India', 'Rainfall', 'English') THEN 1 ELSE 0 END
+ CASE WHEN field3 IN ('India', 'Rainfall', 'English') THEN 1 ELSE 0 END
+ CASE WHEN field4 IN ('India', 'Rainfall', 'English') THEN 1 ELSE 0 END
AS rank
FROM TABLE
WHERE rank > 0
ORDER BY rank
我今天刚从 this answer 了解到CASE WHEN这是关于一个几乎相同的问题。按照我设置的方式,如果 field1 在关键字中,它应该返回 1,如果 field2 在关键字中,它应该返回 1,依此类推。这为您提供了 rank,一个您可以作为排序依据的新字段。不过,最初的回答者说它不是很有效,因此您可能还想查看该页面上的其他解决方案。
关于具有多个字段的多个关键字的 Php MySql 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7802724/
Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题
我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..
我正在用Ruby编写一个简单的程序来检查域列表是否被占用。基本上它循环遍历列表,并使用以下函数进行检查。require'rubygems'require'whois'defcheck_domain(domain)c=Whois::Client.newc.query("google.com").available?end程序不断出错(即使我在google.com中进行硬编码),并打印以下消息。鉴于该程序非常简单,我已经没有什么想法了-有什么建议吗?/Library/Ruby/Gems/1.8/gems/whois-2.0.2/lib/whois/server/adapters/base.
我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代
我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何
我有一个表单,其中有很多字段取自数组(而不是模型或对象)。我如何验证这些字段的存在?solve_problem_pathdo|f|%>... 最佳答案 创建一个简单的类来包装请求参数并使用ActiveModel::Validations。#definedsomewhere,atthesimplest:require'ostruct'classSolvetrue#youcouldevencheckthesolutionwithavalidatorvalidatedoerrors.add(:base,"WRONG!!!")unlesss
我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢
我有一个具有一些属性的模型:attr1、attr2和attr3。我需要在不执行回调和验证的情况下更新此属性。我找到了update_column方法,但我想同时更新三个属性。我需要这样的东西:update_columns({attr1:val1,attr2:val2,attr3:val3})代替update_column(attr1,val1)update_column(attr2,val2)update_column(attr3,val3) 最佳答案 您可以使用update_columns(attr1:val1,attr2:val2
我正在尝试修改当前依赖于定义为activeresource的gem:s.add_dependency"activeresource","~>3.0"为了让gem与Rails4一起工作,我需要扩展依赖关系以与activeresource的版本3或4一起工作。我不想简单地添加以下内容,因为它可能会在以后引起问题:s.add_dependency"activeresource",">=3.0"有没有办法指定可接受版本的列表?~>3.0还是~>4.0? 最佳答案 根据thedocumentation,如果你想要3到4之间的所有版本,你可以这
我知道我可以指定某些字段来使用pluck查询数据库。ids=Item.where('due_at但是我想知道,是否有一种方法可以指定我想避免从数据库查询的某些字段。某种反拔?posts=Post.where(published:true).do_not_lookup(:enormous_field) 最佳答案 Model#attribute_names应该返回列/属性数组。您可以排除其中一些并传递给pluck或select方法。像这样:posts=Post.where(published:true).select(Post.attr