Product search by name and brand

2

I have two tables, one called tags with the product tags and another called products . Within this table products have shirts, pants and etc. I want him to do a search, for example "Hollister shirt," he will return all shirts with the Hollister brand. can anybody help me?

Table 'produto' (
  'item_id' bigint(20) NOT NULL AUTO_INCREMENT,
  'item_name' varchar(50) NOT NULL,
  'item_slug' varchar(50) NOT NULL,
  'item_brand_id' bigint(20) DEFAULT NULL,
  PRIMARY KEY ('item_id')
) 

ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1432 ;

TABLE 'marcas' (
  'item_brand_id' bigint(20) NOT NULL AUTO_INCREMENT,
  'item_brand_name' varchar(50) NOT NULL,
  'item_brand_slug' varchar(50) NOT NULL,
  'item_brand_image' mediumtext NOT NULL,
  'item_brand_color' varchar(6) NOT NULL DEFAULT 'ffffff',
  'item_brand_priority' bigint(20) NOT NULL DEFAULT '0',
  PRIMARY KEY ('item_brand_id')
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=319 ;
    
asked by anonymous 07.03.2014 / 17:04

5 answers

3

Prepare the data

First you need to prepare the data that the user gives you, that is, whether it is indicated camisa Hollister or Hollister camisa , you should find results assuming the brand and product exist:

$search_term = "camisa Hollister";

$search_arr = explode(' ', $search_term);

$append_produtos = "";
$append_marcas = "";
foreach ($search_arr as $term) {
    $append_produtos.= "p.item_name LIKE '%".$term."%' OR ";
    $append_marcas.= "m.item_brand_name LIKE '%".$term."%' OR ";
}

Inquiry

Now that we have the supplied search terms ready to apply to our query, we will prepare the same by relating the two tables, collecting only records from the produtos table that has a relation to the marca table through the item_brand_id column %:

$query = "SELECT p.* FROM produtos p
INNER JOIN marcas m ON (m.item_brand_id = p.item_brand_id)
WHERE (".rtrim($append_produtos, "OR ").") AND (".rtrim($append_marcas, "OR ").")";

Explanation

The query would look like this:

SELECT p.* FROM produtos p
INNER JOIN marcas m ON (m.item_brand_id = p.item_brand_id)
WHERE (p.item_name LIKE '%camisa%' OR p.item_name LIKE '%Hollister%')
AND (m.item_brand_name LIKE '%camisa%' OR m.item_brand_name LIKE '%Hollister%')
What is to be done is to query all the records in the produtos table that contain a value in the item_brand_id column that is equal to the value of the item_brand_id column of the marcas table where the record in the marcas table % contains any of the words given and the record in the produto table contains any of the words given.

Functions used in this response:

07.03.2014 / 17:39
1

The biggest difficulty is to prepare the "LIKE" clause appropriately , since the user can type "%" or other characters with special meaning in your search.

function like($string, $e)
{
    return str_replace(array($e, '_', '%'), array($e.$e, $e.'_', $e.'%'), $string);
}

function like_clauses($campo, $termos)
{
    $clauses = array();

    foreach ($termos as $termo)
    {
        $clause = 
            '(' . $campo
            . ' LIKE "%'
            . mysqli_real_escape_string(like($termo, '='))
            . '%" ESCAPE "=")';

        $clauses[] = $clause;
    }

    return $clauses;
}

We can use the like_clauses function above, giving the name of the search field and a list of words (terms), to get their appropriately formatted LIKE clauses.

function minha_busca($busca)
{
    $termos = array();

    foreach (explode(' ', $busca) as $palavra)
    {
        $termo = trim($palavra);

        if (!empty($termo))
        {
            $termos[] = $termo;
        }
    }

    $termos = array_unique($termos);

    if (empty($termos))
    {
        return array();
    }

    // até aqui apenas limpamos a entrada
    // garantindo a existência de pelo menos um termo de busca

    $sql = sprintf(
        'SELECT item_brand_id FROM marcas WHERE %s',
        implode(' OR ', like_clauses('item_brand_name', $termos))
    );

    // com este primeiro SELECT, obtemos as MARCAS

    $brand_ids = array();

    /* rodar SQL, fazer loop nos resultados, incluir os item_brand_ids em $brand_ids */

    $sql = sprintf(
        'SELECT * FROM produto WHERE %s AND (%s)',
        empty($brand_ids) ? 'TRUE' : 'item_brand_id IN (' . implode(', ', $brand_ids) . ')',
        implode(' OR ', like_clauses('item_name', $termos))
    );

    // com este segundo SELECT, obtemos os produtos, restringidos (ou não) pelas marcas

    $produtos = array();

    /* rodar SQL, fazer loop nos resultados, incluir os registros em $produtos */

    return $produtos;
}

To use the minha_busca function above, and check the results:

$busca = $_POST['busca'];

$resultado = minha_busca($busca);

print_r($resultado);

Remarks :

  • The use of mysqli_real_escape_string assumes that the mysqli extension is in use, with an active connection.

  • In the minha_busca function you still have to fill in the code that executes SQL and makes the loops in the results.

08.03.2014 / 15:55
0

You can use the SQL LIKE operator. Depending on how your tables are. I will show an example of how to do with PHP PDO:

public function get_product( $product_name ) {
  $sql  = "SELECT * FROM produto LIKE :product_name";
  $stmt = Connection::prepare( $sql );
  $stmt->execute();

  return $stmt->fetchAll();
}
    
07.03.2014 / 17:11
0

It was not very clear. Do you want the SELECT of the tables, or do you want to know how to connect PHP and database?

The query will look something like this:

SELECT * FROM produto 
LEFT JOIN marcas
ON produto.item_brand_id = marcas.item_brand_id
WHERE marcas.item_brand_name = 'Hollister'
AND (não entendi como tu sabe o que é camisa, o que é bermuda, etc. 
Mas aqui iria o critério para ver o que é camisa)

Or it may be that you do not know how to make php "chat" with the bank. I advise you to use the documentation.

link

link

    
07.03.2014 / 17:33
0

An idea I have is the following, create a view with the data you need, then when someone does a search, you make your select in that view.

View example

CREATE VIEW 'produto_marca' AS
SELECT CONCAT_WS(' ', p.item_name, m.item_brand_name) as item
FROM produto p
LEFT JOIN marcas m ON m.item_brand_id = p.item_brand_id

Query example

SELECT * FROM produto_marca WHERE item LIKE '%camisa hollister%'

Remembering that this is an idea, so I made it as simple as possible and in view you will probably need more fields.

    
07.03.2014 / 17:37