could someone help me with basic search? I just can't figure it out. My search works only if I type 1 word. But if I type 2,3,4,... words it doesn't work.
Example : POLYKARBONÁTOVÉ POUZDRO NA MACBOOK (Polycarbonate cover for Macbook)
If I type to search input just "pouzdro" it returns all covers. If I type "Polykarbonátové pouzdro" it return nothing. If I type "Polykarbonátové" it returns nothing.
Here is my code:
if ($keyword != null) {
$keyword = strtolower(preg_replace('/\p{Mn}/u', '', \Normalizer::normalize($keyword, \Normalizer::FORM_KD)));
$keywords = explode(' ', $keyword);
$i = 0;
foreach ($keywords as $key) {
$i++;
if ($i == 1) {
$qb->where("p.title LIKE :keyword$i");
} else {
$qb->andWhere("p.title LIKE :keyword$i");
}
$qb->setParameter("keyword$i", "%" . $key . "%");
}
}
Thank you :)
EDIT: Query from the log(I am using postgresql):
[2016-10-26 16:47:11] doctrine.DEBUG: SELECT p0_.id AS id_0, p0_.serial_number AS serial_number_1, p0_.title AS title_2, p0_.url AS url_3, p0_.note AS note_4, p0_.views AS views_5, p0_.price AS price_6, p0_.bought_price AS bought_price_7, p0_.old_price AS old_price_8, p0_.is_active AS is_active_9, p0_.is_accessory AS is_accessory_10, p0_.is_special AS is_special_11, p0_.quantity AS quantity_12, p0_.created_at AS created_at_13, p0_.updated_at AS updated_at_14, p0_.details_id AS details_id_15, p0_.accessory_category_id AS accessory_category_id_16 FROM products p0_ WHERE p0_.title LIKE ? ["%polykarbonatove%"] []
[2016-10-26 16:53:52] doctrine.DEBUG: SELECT p0_.id AS id_0, p0_.serial_number AS serial_number_1, p0_.title AS title_2, p0_.url AS url_3, p0_.note AS note_4, p0_.views AS views_5, p0_.price AS price_6, p0_.bought_price AS bought_price_7, p0_.old_price AS old_price_8, p0_.is_active AS is_active_9, p0_.is_accessory AS is_accessory_10, p0_.is_special AS is_special_11, p0_.quantity AS quantity_12, p0_.created_at AS created_at_13, p0_.updated_at AS updated_at_14, p0_.details_id AS details_id_15, p0_.accessory_category_id AS accessory_category_id_16 FROM products p0_ WHERE p0_.title LIKE ? AND p0_.title LIKE ? ["%polykarbonatove%","%pouzdro%"] []
So,
You don't really need this
LOWER() // LIKE is not case sensitive
Try to clear your code, you should code on this way
foreach ($keywords as $key) { $i++; if ($i == 1) { $qb->where("p.title LIKE :keyword$i"); } else { $qb->andWhere("p.title LIKE :keyword$i"); } $qb->setParameter("keyword$i", "%" . $key . "%"); }
Can you open the log file and give us the real query which doctrine tried (var/cache/logs/dev.log)
The problem you encountered isn't about the number of searched terms, but about accents.
If you want to perform a search without accents, you can change the collation to utf8_general_ci
, which is accent insensitive.
To change the collation with Doctrine, you'll have to implement a custom DQL function, as explained here and implemented in this answer from hattila :
namespace MyCompany\MyBundle\DQL;
use Doctrine\ORM\Query\AST\Functions\FunctionNode;
use Doctrine\ORM\Query\Lexer;
class CollateFunction extends FunctionNode
{
public $expressionToCollate = null;
public $collation = null;
public function parse(\Doctrine\ORM\Query\Parser $parser)
{
$parser->match(Lexer::T_IDENTIFIER);
$parser->match(Lexer::T_OPEN_PARENTHESIS);
$this->expressionToCollate = $parser->StringPrimary();
$parser->match(Lexer::T_COMMA);
$parser->match(Lexer::T_IDENTIFIER);
$lexer = $parser->getLexer();
$this->collation = $lexer->token['value'];
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
}
public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
{
return sprintf( '%s COLLATE %s', $this->expressionToCollate->dispatch($sqlWalker), $this->collation );
}
}
Then add it to Symfony as explained here .
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.