【问题标题】:Symfony/Doctrine - SearchSymfony/Doctrine - 搜索
【发布时间】:2016-10-26 13:03:14
【问题描述】:

有人可以帮助我进行基本搜索吗? 我就是想不通。 只有当我输入 1 个单词时,我的搜索才有效。但是如果我输入 2,3,4,... 单词,它就不起作用了。

示例:POLYKARBONÁTOVÉ POUZDRO NA MACBOOK(Macbook 的聚碳酸酯封面)

如果我输入“pouzdro”来搜索输入,它会返回所有封面。 如果我输入“Polykarbonátové pouzdro”,它什么也不返回。 如果我输入“Polykarbonátové”,它什么也不返回。

这是我的代码:

    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 . "%");
        }
    }

谢谢你:)

编辑: 从日志中查询(我用的是postgresql):

[2016-10-26 16:47:11] 学说.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 买了_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 Accessories_category_id_16 FROM products p0_ WHERE p0_.title LIKE ? ["%polykarbonatove%"] []

[2016-10-26 16:53:52] 学说.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 买了_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 Accessories_category_id_16 FROM products p0_ WHERE p0_.title LIKE ?和 p0_.title 喜欢? ["%polykarbonatove%","%pouzdro%"] []

【问题讨论】:

    标签: php symfony doctrine-orm


    【解决方案1】:

    所以,

    1. 你真的不需要这个

      LOWER() // LIKE is not case sensitive
      
    2. 尝试清除你的代码,你应该这样编码

      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 . "%");
      }
      
    3. 你能打开日志文件,给我们教义尝试过的真实查询吗(var/cache/logs/dev.log)

    【讨论】:

      【解决方案2】:

      您遇到的问题不在于搜索词的数量,而在于口音。

      如果要执行不带重音的搜索,可以将排序规则更改为utf8_general_ci,它不区分重音。

      要使用 Doctrine 更改排序规则,您必须实现自定义 DQL 函数,如 here 所述并在 this answer 中从 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 );
          }
      }
      

      然后将其添加到 Symfony as explained here

      【讨论】:

      • 谢谢,应该这样吗?或 $qb->where("p.title LIKE COLLATE(:keyword$i, utf8_general_ci)"); ?因为我得到了这个:SQLSTATE [42704]:未定义对象:7 错误:用于编码“UTF8”的排序规则“utf8_general_ci”不存在
      • 在研究了您的错误之后,您似乎必须将整个数据库的排序规则更改为排序规则C,因为postgresql 不允许这样更改排序规则。我建议你看看这个答案stackoverflow.com/a/35795540/4074148 或其他人,但我认为它超出了这个问题的范围。
      猜你喜欢
      • 1970-01-01
      • 2016-05-23
      • 2020-06-09
      • 1970-01-01
      • 1970-01-01
      • 2016-07-18
      • 2014-04-19
      • 2016-06-26
      • 1970-01-01
      相关资源
      最近更新 更多