简体   繁体   中英

mySql - search query based on keywords

I wasn't able to find anything that really helped me out with this. I have a database with the following structure:

在此输入图像描述

and a simple query to search and display some results from the DB:

if ($_REQUEST['search']) {
    $q = $_REQUEST['search'];
    $q_comma = explode(", ", $q);
    $where_in_set = '';
    $count = count($q_comma);

    foreach ($q_comma as $q) {
        $counter++;
        if ($counter == $count) {
            $where_in_set .= "FIND_IN_SET('$q','keywords')";
        } else {
            $where_in_set .= "FIND_IN_SET('$q','keywords') AND ";
        }
    }


    $sql_res = "select link, description, keyword from myDB where $where_in_set or description like '%$q%'";

This code works, but not really as I wanted.

In the keyword column, I have different comma separated keywords, and i'd like to be able to search for them even if the order is different.

Here's an example: Let's say I have into my keyword column

Google, Facebook, twitter

With my current code if I type Google, I can see the result, but if i type twitter, I don't see it.

Is there anything I can do to make it work without taking into account the order of the keywords, but having a pretty fast search as well?

Any help will be really appreciated.

PS. I'd like to keep only one DB if possible, cause I read about creating a new table with only ID and keywords, and on my search join the tables on the ID's, but I would prefer a better solution if possible.

Thanks

EDIT

Some updates:

  1. as pointed out by @Frayne Konok, i have the query in lowcase and all the value in the db in lowcase as well, so case cannot be the problem
  2. As suggested by @mkaatman, i wrapped keyword column around backticks (`)
  3. I changed my query so that now it looks like the one suggested by @user2272989 in the answer

So my query now looks like this:

select link, description, keyword from myDB
where (FIND_IN_SET('google',`keyword`) or
       FIND_IN_SET('facebook', `keyword`) or 
       FIND_IN_SET('twitter', `keyword`))
       OR description like 'google, facebook, twitter'

And it is returning values even if the order is different, but it is not showing only the one i want. For example, if i write twitter, google, facebook, i have as a return something like 28 rows, where only 2 have all of the three words as a keyword, while the other my have only one or two

EDIT 2 - Updates

I just want to "reopen" this question since I didn't manage to solve this. If I change all the keywords into an object, will then be better to use them as keywords? or what is the absolute best and more reliable way to search a database for keywords? Having different DBs and use an INNER JOIN?

At this point I'm willing to change the structure and the code if it helps.

Thanks

This may help you

$sql_res = "select link, description, keyword from myDB 
      where (FIND_IN_SET('yahoo',keyword) or
             FIND_IN_SET('twitter',keyword)) or 
             description like '%$q%'";

You are using AND condition in FIND_IN_SET

I ended up using this structure and query here:

$q = $_REQUEST['search'];
$q_comma = array_filter(explode(' ', str_replace(',', ' ', $q)));
$count = count($q_comma);
$dbQuery = "select id, link, description, tags from db where ";
$searchTerms = '';

foreach ($q_comma as $q) {
    $counter++;
    if ($counter == 1) {
        $searchTerms .= "tags LIKE '%$q%'";
    } else {
        $searchTerms .= "and tags LIKE '%$q%'";
    }
}


$sql_res = $dbQuery . $searchTerms;
$result = mysqli_query($db, $sql_res) or die(mysqli_error($db));
$return_arr = array();
$data = array();
if (mysqli_num_rows($result) == 0) {
    echo "Nothing";
} else {
    while ($row = mysqli_fetch_object($result)) {
        $data[] = $row;
    }
    mysqli_free_result($result);
    echo json_encode($data);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM