I have a SQL webhosting database with a table described as "Description". Now the database speaks with my app completely fine but I seem to have a issue regarding multiple keywords in a search. As of right now the search will only find the first word typed in the searchbox inside the table 'Description' in my databse. So say if my user types in "Dragon Tattoo" via the searchbox in the app, It will display everything with "Dragon" only.. In conclusion, what is the best method to have my search box list any keywords with multiple words with spaces for an exact match.
Here is my server side PHP for the search function:
function _search($text){
$dbObj=$this->CONN;
$query="SELECT * FROM tatoo_user_info where description LIKE '%$text%' OR name LIKE '%$text%' ORDER BY create_date DESC";
$stmt=$dbObj->prepare($query);
$res=$stmt->execute();
$rows=$stmt->fetchAll(PDO::FETCH_ASSOC);
$resultant=array();
foreach($rows as $values){
$array=array();
$array=$values;
$query1="SELECT * FROM images where tui_id=:id";
$stmt1=$dbObj->prepare($query1);
$stmt1->bindParam(':id',$values['id']);
$res=$stmt1->execute();
$row=$stmt1->fetchAll(PDO::FETCH_ASSOC);
$arr_image=array();
foreach($row as $images){
$arr_image[]=$images['name'];
}
$resultant[]=array_merge($array,array("images"=>$arr_image));
}
//print_r($resultant);die;
if(count($resultant)>=1){
$result_a=array("status"=>"SUCCESS","message"=>"Successfully Fetched","data"=>$resultant);
echo json_encode($result_a);
}
else{
$result_a=array("status"=>"FAILURE","message"=>"Fail to find");
echo json_encode($result_a);
}
}
I am not sure about performance for this one but you can try with multiple queries:
$str = "Dragon Tattoo and much more";
$arr_words = explode(" ", $str);
foreach($arr_words as $word)
{
$word = trim($word);
$sql="SELECT * FROM tatoo_user_info where description LIKE '%$word%' OR name LIKE '%$word%' ORDER BY create_date DESC";
}
or you can build one long query:
foreach($arr_words as $word){
$sql .= " OR name LIKE '%$word%' and description LIKE '%$word%'... ";
}
Related
I want to fetching Records On the Basis Of Entered Keywords in the Search Bar.
Suppose I have Below 3 Records in My SQL Table's Column
Beautiful Small Kid.
Beautiful Rabbit in the Zoo.
Natural Water.
Now, If the Search Query contains Beautiful, It will Return First 2 Records.
If the Search Query contains Beautiful (anything), It will Return Nothing.
I want those First 2 Records to be Displayed in this case too, Because It has the same word beautiful like in above searched Query.
Right Now, I am Using
SELECT * FROM table WHERE name LIKE '%value%' ORDER BY id ASC
Is there any Other Query or Method to Achieve Such Sort Of Results ?
SELECT * FROM table WHERE (name LIKE '%value1%') OR (name LIKE '%value2%') ORDER BY id ASC
etc
So, you would have to split up your search string into separate words.
$str = yourinput;
$strarray = (explode(" ",$str));
$query = "SELECT * FROM table WHERE ";
Foreach($strarray as $key=>$value){
If($key > 0){
$query = $query . "OR";
}
$query = $query . " (name LIKE '%" . $value . "%') ";
}
$query = $query . "ORDER BY id ASC";
I am using a search box to find entries in my database.
One column contains the title / name of the thing being looked for.
Then I have a second column which gives a short description as applicable (few words usually)
I am trying to search (with the search box) to match either one or even both of the cells combined. Is that possible, and if yes, how?
You can see my code below which kind of shows what I try to achieve, but in any case, let me illustrate this a bit:
Example:
Database.title = "towel"
Database.description = "red, small"
Now, if I type into my search box "tow%red" I want to find the item.
It obviously does not find it, because the title does not contain "red". But if I search for "towel" only, it might show me different items based on different sizes, colors, or other attributes and the list becomes too long.
Of course I also want to be able to simply search for "%red%small% and still be able to find it, or just search for "towel".
Here is my php code that does the search:
if ( !isset($_REQUEST['term']) ) {
exit;
}
$search = mysql_real_escape_string($_REQUEST['term']);
$queryString = "SELECT * FROM items WHERE title+description LIKE '%{$search}%'";
$query = mysql_query($queryString);
$data = array();
if ( $query && mysql_num_rows($query) )
{
while( $row = mysql_fetch_array($query, MYSQL_ASSOC) )
{
$label = $row['title'];
if ($row['description']) {
$label .= ' — '. $row['description'];
}
$data[] = array(
'label' => $label,
'value' => $row['code']
);
}
}
echo json_encode($data);
flush();
I know the above is not going to work, I just put it that way to make clear what I want.
The working code contains this line instead:
$queryString = "SELECT * FROM items WHERE title LIKE '%{$search}%'";
Add a FULLTEXT (see documentation here) index to title and description.
ALTER TABLE items
ADD FULLTEXT INDEX items_index
(title, description);
This will let you search those colums.
Then build a query like this:
SELECT *
FROM items
WHERE MATCH(title, description)
AGAINST ('SEARCH KEYWORD HERE' IN BOOLEAN MODE);
I don't know if that would help you but
"SELECT * FROM items WHERE CONCAT(title, '', description) LIKE '%{$search}%'";
seems simple unless i'm missing something:
$queryString = "SELECT * FROM items WHERE title LIKE '%{$search}%' OR description LIKE '%{$search}%'";
have you tried this.....?
SELECT * FROM items WHERE `title` LIKE '%{$search}%' OR `description` LIKE '%{$search}%'
I currently use a mysql statement like the one below to search post titles.
select * from table where title like %search_term%
But problem is, if the title were like: Acme launches 5 pound burger and a user searched for Acme, it'll return a result. But if a user searched for Acme burger or Acme 5 pound, it'll return nothing.
Is there a way to get it to return results when a users searches for more than one word? Is LIKE the correct thing to use here or is there something else that can be used?
You could use a REGEXP to match any of the words in your search string:
select *
from tbl
where
title REGEXP CONCAT('[[:<:]](', REPLACE('Acme burger', ' ', '|'), ')[[:>:]]')
Please notice that this will not be very efficient. See fiddle here.
If you need to match every word in your string, you could use a query like this:
select *
from tbl
where
title REGEXP CONCAT('[[:<:]]', REPLACE('Acme burger', ' ', '[[:>:]].*[[:<:]]'), '[[:>:]]')
Fiddle here. But words have to be in the correct order (es. 'Acme burger' will match, 'burger Acme' won't). There's a REGEXP to match every word in any order, but it is not supported by MySql, unless you install an UDF that supports Perl regexp.
To search for a string against a text collection use MATCH() and AGAINST()
SELECT * FROM table WHERE MATCH(title) AGAINST('+Acme burger*')
or why not RLIKE
SELECT * FROM table WHERE TITLE RLIKE 'Acme|burger'
or LIKE searching an array, to have a compilation of $keys
$keys=array('Acme','burger','pound');
$mysql = array('0');
foreach($keys as $key){
$mysql[] = 'title LIKE %'.$key.'%'
}
SELECT * FROM table WHERE '.implode(" OR ", $mysql)
What you need to do is construct a SQL such that, for example:
select * from table where title like "%Acme%" and title like "%burger%"
In short: split the string and create one like for each part.
It might also work with replacing spaces with %, but I'm not sure about that.
The best thing is thing use perform union operation by splitting your search string based on whitespaces,
FOR Acme 5 pound,
SELECT * FROM TABLE WHERE TITLE LIKE '%ACME 5 POUND%'
UNION
SELECT * FROM TABLE WHERE TITLE LIKE '%ACME%'
UNION
SELECT * FROM TABLE WHERE TITLE LIKE '%5%'
UNION
SELECT * FROM TABLE WHERE TITLE LIKE '%POUND%'
Find out a way to give the first query a priority. Or pass the above one as four separate queries with some priority. I think you are using front end tp pass query to data bases, so it should be easy for you.
<?php
$search_term = 'test1 test2 test3';
$keywords = explode(" ", preg_replace("/\s+/", " ", $search_term));
foreach($keywords as $keyword){
$wherelike[] = "title LIKE '%$keyword%' ";
}
$where = implode(" and ", $wherelike);
$query = "select * from table where $where";
echo $query;
//select * from table where title LIKE '%test1%' and title LIKE '%test2%' and title LIKE '%test3%'
I have a PHP search script that searches a MySQL database to answer questions. Currently my database is set out like this...
idquestion = what is the timeanswer = The time is 12:00
This data is then sent to my PHP code:
<?php
mysql_connect("localhost","username","password");
mysql_select_db("database");
if(!empty($_GET['q'])){
$query=mysql_real_escape_string(trim($_GET['q']));
$searchSQL="SELECT * FROM questions WHERE `question` LIKE '%{$query}%' LIMIT 1";
$searchResult=mysql_query($searchSQL);
while($row=mysql_fetch_assoc($searchResult)){
$results="{$row['answer']}";
}
echo $results;
}
?>
Currently, the users query must contain exactly the same text as the question field. My question is; how can I make this work so it triggers a certain for several keywords?
I hope you can understand my question
I think full test search index can help
http://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html SOUNDEX function can be useful in this context too.
You can split query to keywords and generate dynamic SQL but it is inefficient (performance issues SQL injection attacks ) see http://php.net/manual/en/function.split.php
Alternative is to add table QUESTION_KEYWORD(QUESTION_ID,KEYWORD), split question and search this table to find best QUESTION_ID, but full text search index is more efficient. In fact full text search index uses similar data structure to optimize test search.
For an easy quick-fix based on your comment you could do something as simple as this:
// Assuming query string is ?q=make,sponge,cake
$searchSQL="SELECT * FROM questions WHERE ";
$count = 0;
foreach (explode(',', $_GET['q']) as $query) {
$searchSQL .= "`question` LIKE '%" .mysql_real_escape_string(trim($query)) . "%' ";
if ($count++ > 0) {
$searchSQL .= ' OR ';
}
}
$searchSQL .= ' LIMIT 1';
$searchResult = mysql_query($searchSQL);
I have Concatenated in mySQL to produce a field that I can search with. This contains animal as well as owner names and addresses for a client database. I need to be able to search by animal name, owner names and postcode in any order.
Thus if if my name is john smith and i own a dog called Fido and live in postcode AB1 2CD, I want the search to be yield results if any of the following are entered:
"john fido AB1"
"john AB1"
"AB1 john"
"AB1 fido"
"fido 2CD"
"2CD"
"fido"
etc... i.e any of the fields in any order, and also not complete words either so "john fido AB1" should yield the same result as "jo fi AB1"
I currently have this PHP code, taking a single text field on my search page, exploding then imploding it to add % between the search terms:
$list = explode(' ',$_GET["q"]);
$q = implode('%%', $list);
if (!$q) return;
$sql = "SELECT DISTINCT owner.AddressPrim, owner.PostcodePrim,
owner.OwnerSurnamePrim,owner.OwnerForenamesPrim,owner.OwnerID
FROM owner
Inner Join patient ON owner.OwnerID = patient.OwnerID
WHERE CONCAT_WS(' ',owner.AddressPrim, owner.PostcodePrim,
owner.OwnerForenamesPrim,owner.OwnerSurnamePrim,patient.AnimalName) LIKE '%$q%'";
This works for "AB1 john" and "john fido" but not "fido john" as it is out of order in the concatenated field.
Any help greatly appreciated
I think you're going to have to split the keywords and add a query for each keyword in the string of keywords.
So first (in PHP), split the query string and dynamically generate your SQL query, then send it to the database. Here's some pseudocode to show you what I mean:
$keywords = explode(' ', $q);
$sql = "SELECT DISTINCT owner.AddressPrim, owner.PostcodePrim,
owner.OwnerSurnamePrim,owner.OwnerForenamesPrim,
owner.OwnerID
FROM owner
Inner Join patient ON owner.OwnerID = patient.OwnerID";
$first = true;
foreach($keyword in $keywords):
if($first):
$sql += " WHERE ";
$first = false;
else:
$sql += " AND ";
$escaped = mysql_real_escape_string($keyword);
$sql += " CONCAT_WS(' ',owner.AddressPrim, owner.PostcodePrim,
owner.OwnerForenamesPrim,owner.OwnerSurnamePrim,patient.AnimalName)
LIKE '%$escaped%'";
But do beware, this is not going to be anywhere near fast for the size of tables you'll probably encounter in daily operation. You may want to look into a better way of doing fulltext search, whether it means using a library or making a cross-reference table of keywords maintained by triggers.
MySQL's fulltext search (MyISAM tables only!) could be useful to you.
http://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html
You can try this http://www.sphinxsearch.com/
You need dedicated server to run this thing, but if you have one, sphinx will easily solve your problem and your queries won't load database.