Multi word search on multiple columns Symfony Doctrine - php

I am trying to craft a multiword search that will query multiple columns in a table. My code works great thus far for a single column, but as you can imagine using it for more then one column becomes an issue.
If I add orWhere it won't work, and I don't really want to create more for loops because it will become quite cumbersome. Any Ideas?
$query = $request->getParameter("article-search");
$keywords = explode(" ", $query);
for( $i = 1; $i <= count( $keywords ); $i++ ){
$q->addWhere("a.title LIKE ?", "%" . $keywords[$i - 1] . "%");
}

I just did it like this.. Maybe it helps somebody..
$now = "some other parameter";
$parts = explode(" ",trim($searchtext));
$clauses=array();
// static paramtter setted here
$parameters = array(
':now' => $now
);
$i = 0;
foreach ($parts as $part){
// for every word make new search query and parameter
$parameters[":param".$i] = "%".$part."%";
if($i == 0){
$clauses = "v.description LIKE :param".$i." OR v.name LIKE :param".$i." OR v.sale LIKE :param".$i;
} else {
$clauses .= " OR v.description LIKE :param".$i." OR v.name LIKE :param".$i." OR v.sale LIKE :param".$i;
}
$i ++;
}
$qb->select('v')
->from('MyBundle\Entity\Voucher', 'v')
->where('v.date_start <= :now')
->andWhere('v.date_end >= :now')
->andWhere($clauses)
->setParameters($parameters);

Usually I would write this as a query that looks something like the following:
$query = "`where column like '%$keywordOne%' or column like '%keywordTwo%'`";
Though I'm not sure how you implement that with the query-building tool you have there.
Here's a quick example that might help build the where portion of the query using the array of keywords you have:
<?php
$keywords = array("bing", "bang", "jump");
$query_start = 'where colummName';
$like_portion = "like '%" . implode("%' or columnName like '%", $keywords) . "%'";
if(sizeof($keywords) > 0) {
echo "`$query_start $like_portion`";
} else {
// No keywords
}
?>
Let me know if there's anything I can clarify here

Maybe you can consider using "union"? Also, for such complex queries, I would use native SQL instead of ORM practice.

Related

Search mysql database by phrase or seperate key words

Ok so when a user types their search phrase in the search input, I would like it to match the exact phrase or the key words entered.
I.e
So the title of a post is "Search the Database"
$searchVal = "Search database";
WHERE post_title LIKE '%" . $searchVal . "%'
The above code doesn't find a match as the title has "the" between Search Database.
How could I get it to match.
I thought maybe using explode but Im getting an error:
$sVals = explode(" ", $searchVal);
foreach ($sVals as $s) {
$querySearchVals .= "OR post_title LIKE '%" . $s . "%'";
}
Hope that makes sense.
Cheers
Maybe this could help
$search_key = $_POST['searchkey']; //take the search text from the post method
$search_words = array();
$search_words = explode(" ",$search_key);
$q_string = "";
$last_index = intval(count($search_Words)) - 1;
for($i = 0; $i<count($search_Words);$i++)
{
$q_string = $q_string . " post_title LIKE '%$search_words[$i]%' ";
if($i != $last_index)
$q_string = $q_string . " OR ";
}
And to make it even more accurate, you may skip the articles like A, The, An etc
You may want to insert the % in between the words and execute with 1 where clause. some thing like below should work.
$searchVal = "Search database";
$querySearchVals = "post_title LIKE '%";
$sVals = explode(" ", $searchVal);
foreach ($sVals as $s) {
$querySearchVals .= $s."%";
}
$querySearchVals .= "'";
echo $querySearchVals;
Hope it helps!

Building multi word LIKE Prepared statement for PDO query

I am trying to build the logic to create a multi word LIKE statement for use with PDO.
This takes the search string $str to build the multiple parts of the LIKE section:
$str = $_POST['str'];
$keywords = preg_split('/[\s]+/', $str);
$totalKeywords = count($keywords);
$search = "%$str%";
$sql_str = " AND post_content LIKE :search0 ";
for($i=1 ; $i < $totalKeywords; $i++){
$search_bit = ":search" . $i;
$sql_str .= " AND post_content LIKE $search_bit ";
}
This is the SQL statement - with the $sql_str slotted into the correct point:
$sql = "SELECT d.ID
, d.post_date
, d.post_content
, d.post_cat_id
, d.post_label
, c.fld_cat
FROM tbl_log_days d
, tbl_log_cats c
WHERE d.post_cat_id = c.fld_id " . $sql_str . "
ORDER BY post_date";
Then for binding the variables, I have tried two approaches:
$stmt = $pdo->prepare($sql);
if (!empty($sql_str)) {
foreach ($keywords as $key => &$keyword){
$foo = '%'.$keyword.'%';
$stmt->bindParam(':search' . $key, $foo);
}
}
And also this (without the ampersand before the $keyword in the foreach line):
$stmt = $pdo->prepare($sql);
if (!empty($sql_str)) {
foreach ($keywords as $key => $keyword){
$foo = '%'.$keyword.'%';
$stmt->bindParam(':search' . $key, $foo);
}
}
However, when I search for e.g. "past hill" and check the resulting SQL that is actually run (I enabled query logging in MySQL), it only takes the last word in the search string:
SELECT d.ID
, d.post_date
, d.post_content
, d.post_cat_id
, d.post_label
, c.fld_cat
FROM tbl_log_days d
, tbl_log_cats c
WHERE d.post_cat_id = c.fld_id AND post_content LIKE '%past%' AND post_content LIKE '%past%'
ORDER BY post_date
I have done a var_dump of the $keyword variable when running a search and it returns:
string(4) "hill"
string(4) "past"
I can't work this one out. Is it possible to do what I'm trying to do?
I would do something like this
for($i=1 ; $i < $totalKeywords; $i++){
$search_num = "search" . $i;
$search_bit = ":" . $search_num;
$sql_str .= " AND post_content LIKE $search_bit ";
$foo = '%'.$keyword.'%';
$V[$search_bit] = $foo;
}
$query = $pdo->prepare($sql);
$query->execute($V);
(I haven't tested this code, so please excuse typos.)
I asked the same question on Sitepoint:
https://www.sitepoint.com/community/t/multi-word-like-prepared-statement-for-pdo-query/223738/5
And got a solution there:
$stmt = $pdo->prepare($sql);
if (!empty($sql_str)) {
for ($x = 0; $x<$totalKeywords; $x++) {
// add the percent signs, or make a new copy of the array first if you want to keep the parameters
$keywords[$x] = "%" . $keywords[$x] . "%";
$stmt->bindParam(':search' . $x, $keywords[$x]);
}
}

Trying to implement multiple keyword search but unable to get the desire results

I am trying to implement a multiple and keyword search in my application, but it searches only for the last word in the input and ignores the rest of the input can someone please help me with issue, below is my code...
$where_clause=array();
if(!empty($vResume_screen))
{
// trim whitespace from the stored variable
$trimmed = trim($vResume_screen);
// separate key-phrases into keywords
$trimmed_array = explode(" ",$trimmed);
// count keywords
$trimm_total = count($trimmed_array);
$i = 0;
$searchstring = '';
// looping to get the search string
foreach ($trimmed_array as $trimm)
{
if ($i != 0 and $i != $wordcount)
{
$searchstring .= " AND ";
}
$searchstring .= "resume_text LIKE '%$trimm%'";
// incrementing the value
$i = $i + 1;
}
$where_clause[]="resume_text like '%".$searchstring."%'";
}
I just changed your code a little bit, take a look...
$where_clause=array();
if(!empty($vResume_screen))
{
// separate key-phrases into keywords
$trimmed_array = explode(" ", trim($trimmed));
// count keywords
$trimm_total = count($trimmed_array);
$searchstring = '';
// looping to get the search string
foreach ($trimmed_array as $trimm)
{
if (!empty($searchstring)) {
$searchstring .= " OR "; //If you want to put the same condition for different keywords, you need to use OR.
}
$searchstring .= " resume_text LIKE '%" . $trimm . "%' ";
}
array_push($where_clause, $searchstring);
}
I dont know why you need the $where_clause to be an array but i did not change...

return a php incremented string as a mysql snippet

I have a search get variable that can contain multiple words which are space deliminated. I have used the following to script to grab the url variable. Notice for the example I have just used a string for simplicity.
What I have tried to do is explode the variable value and then add on the needed sql before and after.
The echo works fine. It is this echo that I need as a variable in a sql within the code that follows.
My problem is that it just returns the last query metal when I reference it outside within the query as a string. I am so new to this, please any help would appreciated.
<?php
$string = "kitchens wooden metal";
$splitted = explode(" ",$string);
$cnt = count($splitted);
$i=0;
while($cnt > $i)
{
$sqlsnippet = "cats_sub.cats_sub_ms_desc LIKE %$splitted[$i]%";
$i++;
echo $sqlsnippet;
}
?>
$sqlsnippet = "cats_sub.cats_sub_ms_desc LIKE %$splitted[$i]%";
This overrides $sqlsnippet for every iteration of the while-loop. That's the reason why you only get the last SQL snippet.
You need to concatenate the SQL snippets, like this:
$sqlsnippet = 'WHERE ';
foreach($i = 0; $i < count($splitted); $i++)
{
// Append AND
if($i > 0)
{
$sqlsnippet .= ' AND ';
}
$sqlsnippet .= 'cats_sub.cats_sub_ms_desc LIKE %' . mysql_real_escape($splitted[$i]) . '%';
}
var_dump($sqlsnippet);
My code:
<?php
$string = "kitchens wooden metal";
$splitted = explode(" ",$string);
$cnt = count($splitted);
$i=0;
while($cnt > $i)
{
$sqlsnippets[] = "cats_sub.cats_sub_ms_desc LIKE '%$splitted[$i]%'";
$i++;
}
$sqlsnippet = "(" . implode(" or ", $sqlsnippets) . ")";
echo $sqlsnippet;
?>
Result:
(cats_sub.cats_sub_ms_desc LIKE '%kitchens%' or cats_sub.cats_sub_ms_desc LIKE '%wooden%' or cats_sub.cats_sub_ms_desc LIKE '%metal%')
Optimized version:
<?php
$string = "kitchens wooden metal";
$sqlsnippet = "(cats_sub.cats_sub_ms_desc LIKE '%" . preg_replace("/ /", "%' or cats_sub.cats_sub_ms_desc LIKE '%", $string) . "%')";
echo $sqlsnippet;
?>

Add parts of a php mysql array together in little bunches? Leave out other parts of same array?

How can I change the code below so each part is added together in a little bunch instead of smushed together? If a little part that appears on the screen is 123, it should add 12+3 and display 15 instead of 123. I have tried sum_array and other things but it won't work to add PARTS with other PARTS in little bunches. I can only get it to display smushed together results how it is below, or add the wrong parts or the whole thing other ways.
$data = mysql_query('SELECT weight FROM my_table WHERE session_id = "' . session_id() . '"');
$params = array();
while ($row = mysql_fetch_assoc($data)) {
$params[] = $row['weight'];
}
$combinations=getCombinations($params);
function getCombinations($array)
{
$length=sizeof($array);
$combocount=pow(2,$length);
for ($i=1; $i<$combocount; $i++)
{
$binary = str_pad(decbin($i), $length, "0", STR_PAD_LEFT);
$combination='';
for($j=0;$j<$length;$j++)
{
if($binary[$j]=="1")
$combination.=$array[$j];
}
$combinationsarray[]=$combination;
echo $combination . "<br>";
}
return $combinationsarray;
}
It looks like
$combination.=$array[$j];
is your problem . in PHP is used for String Concatenation and not math. Because PHP is a loosely data typed language you are telling PHP to take the String value of $array[$j] and ".=" (append) it to $combination giving you the 12 .= 3 == "123" problem and not 15 like what you want. You should try += instead.
If I understand what you're trying to do, I think you want to use addition + instead of concatination . in the following line:
if($binary[$j]=="1")
$combination += $array[$j];

Categories